From 4d15e0dbd28fa5f89e6d06579a54374023ccd4dc Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 8 Apr 2024 05:03:18 +0000 Subject: [PATCH 01/45] update platform version --- composer.json | 2 +- composer.lock | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 186ba1eff3..f7d4f700cb 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "utopia-php/messaging": "0.3.*", "utopia-php/migration": "0.3.*", "utopia-php/orchestration": "0.9.*", - "utopia-php/platform": "0.5.*", + "utopia-php/platform": "0.6.*", "utopia-php/pools": "0.4.*", "utopia-php/preloader": "0.2.*", "utopia-php/queue": "0.7.*", diff --git a/composer.lock b/composer.lock index c8040a54de..58121bc9fc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d4bead528175f70ccaf4f4b8ec03a486", + "content-hash": "9df8a86d34f06281d71fc7ad4e70a563", "packages": [ { "name": "adhocore/jwt", @@ -1796,16 +1796,16 @@ }, { "name": "utopia-php/platform", - "version": "0.5.1", + "version": "0.6.0", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285" + "reference": "6512e761f14f3bf3e510c2f2fdeb064e239d9634" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/3eceef0b6593fe0f7d2efd36d40402a395a4c285", - "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/6512e761f14f3bf3e510c2f2fdeb064e239d9634", + "reference": "6512e761f14f3bf3e510c2f2fdeb064e239d9634", "shasum": "" }, "require": { @@ -1813,7 +1813,8 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.*.*" + "utopia-php/framework": "0.33.*", + "utopia-php/queue": "0.7.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -1839,9 +1840,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.1" + "source": "https://github.com/utopia-php/platform/tree/0.6.0" }, - "time": "2023-12-26T16:14:41+00:00" + "time": "2024-04-08T04:49:05+00:00" }, { "name": "utopia-php/pools", From 8fe6ce64b212521d8e4a807a31bc84b01fdc5eae Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 8 Apr 2024 05:05:04 +0000 Subject: [PATCH 02/45] create and use core module --- src/Appwrite/Platform/Appwrite.php | 1 + src/Appwrite/Platform/Core.php | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 src/Appwrite/Platform/Core.php diff --git a/src/Appwrite/Platform/Appwrite.php b/src/Appwrite/Platform/Appwrite.php index 05224799f3..289abd9429 100644 --- a/src/Appwrite/Platform/Appwrite.php +++ b/src/Appwrite/Platform/Appwrite.php @@ -10,6 +10,7 @@ class Appwrite extends Platform { public function __construct() { + parent::__construct(new Core()); $this->addService('tasks', new Tasks()); $this->addService('workers', new Workers()); } diff --git a/src/Appwrite/Platform/Core.php b/src/Appwrite/Platform/Core.php new file mode 100644 index 0000000000..1081a9800f --- /dev/null +++ b/src/Appwrite/Platform/Core.php @@ -0,0 +1,9 @@ + Date: Mon, 8 Apr 2024 05:08:55 +0000 Subject: [PATCH 03/45] fix change --- src/Appwrite/Platform/Services/Tasks.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index 8b0cba8e16..89436ba7be 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -11,7 +11,6 @@ use Appwrite\Platform\Tasks\Schedule; use Appwrite\Platform\Tasks\SDKs; use Appwrite\Platform\Tasks\Specs; use Appwrite\Platform\Tasks\SSL; -use Appwrite\Platform\Tasks\Usage; use Appwrite\Platform\Tasks\Vars; use Appwrite\Platform\Tasks\Version; use Appwrite\Platform\Tasks\Upgrade; @@ -20,7 +19,7 @@ class Tasks extends Service { public function __construct() { - $this->type = self::TYPE_CLI; + $this->type = Service::TYPE_TASK; $this ->addAction(Version::getName(), new Version()) ->addAction(Vars::getName(), new Vars()) From 5e12eaa2e34bcada769f30e632aaca2f692e47be Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 8 Apr 2024 05:09:51 +0000 Subject: [PATCH 04/45] fix type --- app/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/cli.php b/app/cli.php index 4e1df30f9a..aa6de571ad 100644 --- a/app/cli.php +++ b/app/cli.php @@ -174,7 +174,7 @@ CLI::setResource('logError', function (Registry $register) { }, ['register']); $platform = new Appwrite(); -$platform->init(Service::TYPE_CLI); +$platform->init(Service::TYPE_TASK); $cli = $platform->getCli(); From a67c6bfacb8ba2b60809251b9785a5da0edce104 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 8 Apr 2024 05:16:37 +0000 Subject: [PATCH 05/45] update platform version --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 58121bc9fc..a9942c81bb 100644 --- a/composer.lock +++ b/composer.lock @@ -1796,16 +1796,16 @@ }, { "name": "utopia-php/platform", - "version": "0.6.0", + "version": "0.6.1", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "6512e761f14f3bf3e510c2f2fdeb064e239d9634" + "reference": "48910f25a9746ed35e8c6952ac1f53ceef0213cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/6512e761f14f3bf3e510c2f2fdeb064e239d9634", - "reference": "6512e761f14f3bf3e510c2f2fdeb064e239d9634", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/48910f25a9746ed35e8c6952ac1f53ceef0213cb", + "reference": "48910f25a9746ed35e8c6952ac1f53ceef0213cb", "shasum": "" }, "require": { @@ -1840,9 +1840,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.6.0" + "source": "https://github.com/utopia-php/platform/tree/0.6.1" }, - "time": "2024-04-08T04:49:05+00:00" + "time": "2024-04-08T05:15:31+00:00" }, { "name": "utopia-php/pools", From 70eb56a38863e093408859cd152de7c742beb829 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 8 Apr 2024 05:25:55 +0000 Subject: [PATCH 06/45] refactor module --- src/Appwrite/Platform/Appwrite.php | 1 + src/Appwrite/Platform/{ => Modules}/Core.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename src/Appwrite/Platform/{ => Modules}/Core.php (64%) diff --git a/src/Appwrite/Platform/Appwrite.php b/src/Appwrite/Platform/Appwrite.php index 289abd9429..fac55635d3 100644 --- a/src/Appwrite/Platform/Appwrite.php +++ b/src/Appwrite/Platform/Appwrite.php @@ -4,6 +4,7 @@ namespace Appwrite\Platform; use Appwrite\Platform\Services\Tasks; use Appwrite\Platform\Services\Workers; +use Appwrite\Platform\Modules\Core; use Utopia\Platform\Platform; class Appwrite extends Platform diff --git a/src/Appwrite/Platform/Core.php b/src/Appwrite/Platform/Modules/Core.php similarity index 64% rename from src/Appwrite/Platform/Core.php rename to src/Appwrite/Platform/Modules/Core.php index 1081a9800f..ea73e07690 100644 --- a/src/Appwrite/Platform/Core.php +++ b/src/Appwrite/Platform/Modules/Core.php @@ -1,6 +1,6 @@ Date: Wed, 15 May 2024 20:25:29 +0300 Subject: [PATCH 07/45] adding requests count on error --- app/controllers/shared/api.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 7b218e050a..810254ae6d 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -15,13 +15,11 @@ use Appwrite\Extend\Exception as AppwriteException; use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; -use Appwrite\Utopia\View; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; use Utopia\App; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; -use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\DateTime; From dae9cb995c17fc5667f176e9ed0aa00a5b9fa4f1 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 16 May 2024 21:21:21 +0300 Subject: [PATCH 08/45] adding requests count on error --- app/controllers/shared/api.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 810254ae6d..d1073ee8e7 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -26,10 +26,7 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; -use Utopia\DSN\DSN; -use Utopia\Logger\Log; use Utopia\Logger\Log\User; -use Utopia\Logger\Logger; use Utopia\System\System; use Utopia\Validator\WhiteList; @@ -750,7 +747,7 @@ App::error() ->inject('response') ->inject('project') ->inject('queueForUsage') - ->action(function (Throwable $error, Request $request, Response $response, Document $project, Audit $queueForAudits, Usage $queueForUsage) { + ->action(function (Throwable $error, Request $request, Response $response, Document $project, Audit $queueForAudits, Usage $queueForUsage) { if ($error instanceof AppwriteException) { $publish = $error->isPublishable(); @@ -777,4 +774,4 @@ App::error() ->trigger(); } - }); \ No newline at end of file + }); From e1ac0d622ee92b9f61edc1cc94c93ca0f19db8c5 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 19 May 2024 10:55:14 +0300 Subject: [PATCH 09/45] adding requests count on error --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8865a32d91..e247799645 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "utopia-php/fetch": "0.2.*", "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", - "utopia-php/logger": "0.3.*", + "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.10.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", From 8aabb92fdaccec0bd7964e9e7d3b95d13a82ac8e Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 19 May 2024 13:50:25 +0300 Subject: [PATCH 10/45] adding requests count on error --- app/controllers/shared/api.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index d1073ee8e7..91e7f87113 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -27,6 +27,7 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; use Utopia\Logger\Log\User; +use Utopia\Logger\Logger; use Utopia\System\System; use Utopia\Validator\WhiteList; @@ -755,6 +756,10 @@ App::error() $publish = $error->getCode() === 0 || $error->getCode() >= 500; } + if ($error->getCode() >= 400 && $error->getCode() < 500) { + $publish = true; + } + if ($publish && $project->getId() !== 'console') { if (!Auth::isPrivilegedUser(Authorization::getRoles())) { $fileSize = 0; From 87cf7776df0cc6402a29179e8b769b511679f88c Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 10:59:19 +0300 Subject: [PATCH 11/45] lint --- app/controllers/shared/api.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 91e7f87113..172ded7f31 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -27,7 +27,6 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; use Utopia\Logger\Log\User; -use Utopia\Logger\Logger; use Utopia\System\System; use Utopia\Validator\WhiteList; @@ -757,8 +756,8 @@ App::error() } if ($error->getCode() >= 400 && $error->getCode() < 500) { - $publish = true; - } + $publish = true; + } if ($publish && $project->getId() !== 'console') { if (!Auth::isPrivilegedUser(Authorization::getRoles())) { From a22d98296c81e92e5c629b9a0f93ffc3f6873804 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 16:33:40 +0300 Subject: [PATCH 12/45] lint --- app/controllers/shared/api.php | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index d44efce45d..72708d9b88 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -746,7 +746,7 @@ App::error() ->inject('response') ->inject('project') ->inject('queueForUsage') - ->action(function (Throwable $error, Request $request, Response $response, Document $project, Audit $queueForAudits, Usage $queueForUsage) { + ->action(function (Throwable $error, Request $request, Response $response, Document $project, Usage $queueForUsage) { if ($error instanceof AppwriteException) { $publish = $error->isPublishable(); diff --git a/composer.lock b/composer.lock index bfe8fc0730..8acbbed541 100644 --- a/composer.lock +++ b/composer.lock @@ -5613,5 +5613,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.2.0" } From c996dbcdc911b08525ece4f9de28419e8eb0caf7 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 16:39:23 +0300 Subject: [PATCH 13/45] lint --- app/controllers/general.php | 24 +++++++++++++++++++- app/controllers/shared/api.php | 41 +--------------------------------- 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index f1be7bd614..ca57b27ec6 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -2,6 +2,7 @@ require_once __DIR__ . '/../init.php'; +use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; use Appwrite\Event\Event; use Appwrite\Event\Usage; @@ -646,7 +647,8 @@ App::error() ->inject('project') ->inject('logger') ->inject('log') - ->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log) { + ->inject('queueForUsage') + ->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Usage $queueForUsage) { $version = System::getEnv('_APP_VERSION', 'UNKNOWN'); $route = $utopia->getRoute(); $class = \get_class($error); @@ -735,6 +737,26 @@ App::error() } } + if ($publish && $project->getId() !== 'console') { + if (!Auth::isPrivilegedUser(Authorization::getRoles())) { + $fileSize = 0; + $file = $request->getFiles('file'); + if (!empty($file)) { + $fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size']; + } + + $queueForUsage + ->addMetric(METRIC_NETWORK_REQUESTS, 1) + ->addMetric(METRIC_NETWORK_INBOUND, $request->getSize() + $fileSize) + ->addMetric(METRIC_NETWORK_OUTBOUND, $response->getSize()); + } + + $queueForUsage + ->setProject($project) + ->trigger(); + } + + if ($logger && $publish) { try { /** @var Utopia\Database\Document $user */ diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 72708d9b88..54f9da27c1 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -738,43 +738,4 @@ App::init() if (System::getEnv('_APP_USAGE_STATS', 'enabled') !== 'enabled') { throw new Exception(Exception::GENERAL_USAGE_DISABLED); } - }); - -App::error() - ->inject('error') - ->inject('request') - ->inject('response') - ->inject('project') - ->inject('queueForUsage') - ->action(function (Throwable $error, Request $request, Response $response, Document $project, Usage $queueForUsage) { - - if ($error instanceof AppwriteException) { - $publish = $error->isPublishable(); - } else { - $publish = $error->getCode() === 0 || $error->getCode() >= 500; - } - - if ($error->getCode() >= 400 && $error->getCode() < 500) { - $publish = true; - } - - if ($publish && $project->getId() !== 'console') { - if (!Auth::isPrivilegedUser(Authorization::getRoles())) { - $fileSize = 0; - $file = $request->getFiles('file'); - if (!empty($file)) { - $fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size']; - } - - $queueForUsage - ->addMetric(METRIC_NETWORK_REQUESTS, 1) - ->addMetric(METRIC_NETWORK_INBOUND, $request->getSize() + $fileSize) - ->addMetric(METRIC_NETWORK_OUTBOUND, $response->getSize()); - } - - $queueForUsage - ->setProject($project) - ->trigger(); - } - - }); + }); \ No newline at end of file From a2ef77f0f593b403bab295e820de11f489026610 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 16:47:37 +0300 Subject: [PATCH 14/45] lint --- app/controllers/shared/api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 54f9da27c1..1afd6b652e 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -738,4 +738,4 @@ App::init() if (System::getEnv('_APP_USAGE_STATS', 'enabled') !== 'enabled') { throw new Exception(Exception::GENERAL_USAGE_DISABLED); } - }); \ No newline at end of file + }); From a895ce4270099e9184d201a6c4c9d2951d09b7fb Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 16:51:29 +1200 Subject: [PATCH 15/45] Remove redundant backup checks --- app/controllers/api/projects.php | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 5464014b48..c07c708bd4 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -111,35 +111,8 @@ App::post('/v1/projects') $projectId = ($projectId == 'unique()') ? ID::unique() : $projectId; - $backups['database_db_fra1_v14x_02'] = ['from' => '03:00', 'to' => '05:00']; - $backups['database_db_fra1_v14x_03'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_04'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_05'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_06'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_07'] = ['from' => '00:00', 'to' => '02:00']; - $databases = Config::getParam('pools-database', []); - /** - * Remove databases from the list that are currently undergoing an backup - */ - if (count($databases) > 1) { - $now = new \DateTime(); - - foreach ($databases as $index => $database) { - if (empty($backups[$database])) { - continue; - } - $backup = $backups[$database]; - $from = \DateTime::createFromFormat('H:i', $backup['from']); - $to = \DateTime::createFromFormat('H:i', $backup['to']); - if ($now >= $from && $now <= $to) { - unset($databases[$index]); - break; - } - } - } - $databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE'); $index = \array_search($databaseOverride, $databases); if ($index !== false) { From 4ed125f7c880c6e8ec7dec92e543fd5d91f1d3e0 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 16:53:09 +1200 Subject: [PATCH 16/45] Remove random shared tables assignment in preparation of setting as override instead --- app/controllers/api/projects.php | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index c07c708bd4..f90dda6cab 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -125,33 +125,8 @@ App::post('/v1/projects') throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project."); } - // TODO: 1 in 5 projects use shared tables. Temporary until all projects are using shared tables. - if ( - ( - !\mt_rand(0, 4) - && System::getEnv('_APP_DATABASE_SHARED_TABLES', 'enabled') === 'enabled' - && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' - ) || - ( - $dsn === DATABASE_SHARED_TABLES - ) - ) { - $schema = 'appwrite'; - $database = 'appwrite'; - $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); - $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; - - if (!empty($namespace)) { - $dsn .= '&namespace=' . $namespace; - } - } - - // TODO: Allow overriding in development mode. Temporary until all projects are using shared tables. - if ( - App::isDevelopment() - && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' - && $request->getHeader('x-appwrited-share-tables', false) - ) { + // TODO: Temporary until all projects are using shared tables. + if ($dsn === DATABASE_SHARED_TABLES || (App::isDevelopment() && $request->getHeader('x-appwrite-shared-tables', false))) { $schema = 'appwrite'; $database = 'appwrite'; $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); From e19b465ce2bd48019dd362f24e3fdaf711d5040e Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 20:10:47 +1200 Subject: [PATCH 17/45] Move shared tables db to env var from const --- app/cli.php | 4 ++-- app/controllers/api/projects.php | 6 +++--- app/init.php | 7 ++----- app/realtime.php | 2 +- app/worker.php | 6 +++--- src/Appwrite/Platform/Workers/Deletes.php | 6 +++--- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/app/cli.php b/app/cli.php index da7d23c18d..69d4c1c5a8 100644 --- a/app/cli.php +++ b/app/cli.php @@ -109,7 +109,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -133,7 +133,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index f90dda6cab..26a6431f11 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -126,11 +126,11 @@ App::post('/v1/projects') } // TODO: Temporary until all projects are using shared tables. - if ($dsn === DATABASE_SHARED_TABLES || (App::isDevelopment() && $request->getHeader('x-appwrite-shared-tables', false))) { + if ($dsn === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $schema = 'appwrite'; $database = 'appwrite'; $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); - $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; + $dsn = $schema . '://' . System::getEnv('_APP_DATABASE_SHARED_TABLES', '') . '?database=' . $database; if (!empty($namespace)) { $dsn .= '&namespace=' . $namespace; @@ -184,7 +184,7 @@ App::post('/v1/projects') $adapter = $pools->get($dsn->getHost())->pop()->getResource(); $dbForProject = new Database($adapter, $cache); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $dbForProject ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/init.php b/app/init.php index 57ad5fab87..c6c9c401a7 100644 --- a/app/init.php +++ b/app/init.php @@ -143,9 +143,6 @@ const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite'; const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1'; const APP_HOSTNAME_INTERNAL = 'appwrite'; -// Databases -const DATABASE_SHARED_TABLES = 'database_db_fra1_self_hosted_16_0'; - // Database Reconnect const DATABASE_RECONNECT_SLEEP = 2; const DATABASE_RECONNECT_MAX_ATTEMPTS = 10; @@ -1338,7 +1335,7 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForConsole, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -1391,7 +1388,7 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, ->setMetadata('project', $project->getId()) ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/realtime.php b/app/realtime.php index 2904b1db9c..cde4327417 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -92,7 +92,7 @@ if (!function_exists("getProjectDB")) { $database = new Database($adapter, getCache()); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/worker.php b/app/worker.php index 763ab1d914..5d72d52635 100644 --- a/app/worker.php +++ b/app/worker.php @@ -94,7 +94,7 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -127,7 +127,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -151,7 +151,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 49b41da495..d54f3f5079 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -498,14 +498,14 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { - if ($dsn->getHost() !== DATABASE_SHARED_TABLES || !\in_array($collection->getId(), $projectCollectionIds)) { + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $collectionsIds = \array_map(fn ($collection) => $collection->getId(), $collections); if (empty(\array_diff($collectionsIds, $projectCollectionIds))) { @@ -554,7 +554,7 @@ class Deletes extends Action ], $dbForConsole); // Delete metadata table - if ($dsn->getHost() !== DATABASE_SHARED_TABLES) { + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $dbForProject->deleteCollection('_metadata'); } else { $this->deleteByGroup('_metadata', [], $dbForProject); From 00c047d804aa3d25565552cd9fce941abab2ca76 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 20:29:06 +1200 Subject: [PATCH 18/45] Run full tests on shared tables --- .github/workflows/tests.yml | 3 + docker-compose.yml | 40 +- .../Projects/ProjectsConsoleClientTest.php | 501 ------------------ 3 files changed, 21 insertions(+), 523 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2cc4c700f7..7bc39392ef 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -145,3 +145,6 @@ jobs: - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug + + - name: Run ${{matrix.service}} Shared Tables Tests + run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug diff --git a/docker-compose.yml b/docker-compose.yml index c104102a76..168b5271f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -189,6 +189,7 @@ services: - _APP_CONSOLE_COUNTRIES_DENYLIST - _APP_EXPERIMENT_LOGGING_PROVIDER - _APP_EXPERIMENT_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-realtime: entrypoint: realtime @@ -238,6 +239,7 @@ services: - _APP_USAGE_STATS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-audits: entrypoint: worker-audits @@ -267,6 +269,7 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-webhooks: entrypoint: worker-webhooks @@ -299,6 +302,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_WEBHOOK_MAX_FAILED_ATTEMPTS + - _APP_DATABASE_SHARED_TABLES appwrite-worker-deletes: entrypoint: worker-deletes @@ -356,6 +360,7 @@ services: - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST + - _APP_DATABASE_SHARED_TABLES appwrite-worker-databases: entrypoint: worker-databases @@ -387,6 +392,7 @@ services: - _APP_LOGGING_CONFIG - _APP_WORKERS_NUM - _APP_QUEUE_NAME + - _APP_DATABASE_SHARED_TABLES appwrite-worker-builds: entrypoint: worker-builds @@ -452,6 +458,7 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET + - _APP_DATABASE_SHARED_TABLES appwrite-worker-certificates: entrypoint: worker-certificates @@ -487,6 +494,7 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-functions: entrypoint: worker-functions @@ -526,6 +534,7 @@ services: - _APP_DOCKER_HUB_PASSWORD - _APP_LOGGING_CONFIG - _APP_LOGGING_PROVIDER + - _APP_DATABASE_SHARED_TABLES appwrite-worker-mails: entrypoint: worker-mails @@ -560,6 +569,7 @@ services: - _APP_LOGGING_CONFIG - _APP_DOMAIN - _APP_OPTIONS_FORCE_HTTPS + - _APP_DATABASE_SHARED_TABLES appwrite-worker-messaging: entrypoint: worker-messaging @@ -592,6 +602,7 @@ services: - _APP_SMS_FROM - _APP_SMS_PROVIDER - _APP_SMS_PROJECTS_DENY_LIST + - _APP_DATABASE_SHARED_TABLES appwrite-worker-migrations: entrypoint: worker-migrations @@ -627,6 +638,7 @@ services: - _APP_LOGGING_CONFIG - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET + - _APP_DATABASE_SHARED_TABLES appwrite-task-maintenance: entrypoint: maintenance @@ -664,6 +676,7 @@ services: - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY - _APP_MAINTENANCE_RETENTION_SCHEDULES - _APP_MAINTENANCE_DELAY + - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage: entrypoint: worker-usage @@ -695,6 +708,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage-dump: entrypoint: worker-usage-dump @@ -726,6 +740,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-functions: entrypoint: schedule-functions @@ -753,6 +768,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-messages: entrypoint: schedule-messages @@ -780,6 +796,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_DATABASE_SHARED_TABLES appwrite-assistant: container_name: appwrite-assistant @@ -878,20 +895,7 @@ services: - MYSQL_USER=${_APP_DB_USER} - MYSQL_PASSWORD=${_APP_DB_PASS} - MARIADB_AUTO_UPGRADE=1 - command: "mysqld --innodb-flush-method=fsync" # add ' --query_cache_size=0' for DB tests - # command: mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bu && mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bu - - # smtp: - # image: appwrite/smtp:1.2.0 - # container_name: appwrite-smtp - # restart: unless-stopped - # networks: - # - appwrite - # environment: - # - LOCAL_DOMAINS=@ - # - RELAY_FROM_HOSTS=192.168.0.0/16 ; *.yourdomain.com - # - SMARTHOST_HOST=smtp - # - SMARTHOST_PORT=587 + command: "mysqld --innodb-flush-method=fsync" redis: image: redis:7.2.4-alpine @@ -909,14 +913,6 @@ services: volumes: - appwrite-redis:/data:rw - # clamav: - # image: appwrite/clamav:1.2.0 - # container_name: appwrite-clamav - # networks: - # - appwrite - # volumes: - # - appwrite-uploads:/storage/uploads - # Dev Tools Start ------------------------------------------------------------------------------------------ # # The Appwrite Team uses the following tools to help debug, monitor and diagnose the Appwrite stack diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 62f5cfe435..5e0a48642b 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -9,7 +9,6 @@ use Tests\E2E\General\UsageTest; use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; @@ -3494,504 +3493,4 @@ class ProjectsConsoleClientTest extends Scope return $data; } - - public function testTenantIsolation(): void - { - // Create a team and a project - $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'teamId' => ID::unique(), - 'name' => 'Amazing Team', - ]); - - $teamId = $team['body']['$id']; - - // Project-level isolation - $project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => false - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Application level isolation (shared tables) - $project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => true - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Project-level isolation - $project3 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => false - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Application level isolation (shared tables) - $project4 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => true - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Create and API key in each project - $key1 = $this->client->call(Client::METHOD_POST, '/projects/' . $project1['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key2 = $this->client->call(Client::METHOD_POST, '/projects/' . $project2['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key3 = $this->client->call(Client::METHOD_POST, '/projects/' . $project3['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key4 = $this->client->call(Client::METHOD_POST, '/projects/' . $project4['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - // Create a database in each project - $database1 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database2 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database3 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database4 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - // Create a collection in each project - $collection1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - // Create an attribute in each project - $attribute1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => $collection1['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection2['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => $collection3['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - // Wait for attributes - \sleep(2); - - // Create an index in each project - $index1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => $collection1['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute1['body']['key']], - ]); - - $index2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection2['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute2['body']['key']], - ]); - - $index3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => $collection3['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute3['body']['key']], - ]); - - $index4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute4['body']['key']], - ]); - - // Wait for indexes - \sleep(2); - - // Assert that each project has only 1 database, 1 collection, 1 attribute and 1 index - $databasesProject1 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject1['body']['total']); - $this->assertEquals(1, \count($databasesProject1['body']['databases'])); - - $databasesProject2 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject2['body']['total']); - $this->assertEquals(1, \count($databasesProject2['body']['databases'])); - - $databasesProject3 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject3['body']['total']); - $this->assertEquals(1, \count($databasesProject3['body']['databases'])); - - $databasesProject4 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject4['body']['total']); - $this->assertEquals(1, \count($databasesProject4['body']['databases'])); - - $collectionsProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject1['body']['total']); - $this->assertEquals(1, \count($collectionsProject1['body']['collections'])); - - $collectionsProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject2['body']['total']); - $this->assertEquals(1, \count($collectionsProject2['body']['collections'])); - - $collectionsProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject3['body']['total']); - $this->assertEquals(1, \count($collectionsProject3['body']['collections'])); - - $collectionsProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject4['body']['total']); - $this->assertEquals(1, \count($collectionsProject4['body']['collections'])); - - $attributesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject1['body']['total']); - $this->assertEquals(1, \count($attributesProject1['body']['attributes'])); - $this->assertEquals('available', $attributesProject1['body']['attributes'][0]['status']); - - $attributesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject2['body']['total']); - $this->assertEquals(1, \count($attributesProject2['body']['attributes'])); - $this->assertEquals('available', $attributesProject2['body']['attributes'][0]['status']); - - $attributesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject3['body']['total']); - $this->assertEquals(1, \count($attributesProject3['body']['attributes'])); - $this->assertEquals('available', $attributesProject3['body']['attributes'][0]['status']); - - $attributesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject4['body']['total']); - $this->assertEquals(1, \count($attributesProject4['body']['attributes'])); - $this->assertEquals('available', $attributesProject4['body']['attributes'][0]['status']); - - $indexesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject1['body']['total']); - $this->assertEquals(1, \count($indexesProject1['body']['indexes'])); - - $indexesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject2['body']['total']); - $this->assertEquals(1, \count($indexesProject2['body']['indexes'])); - - $indexesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject3['body']['total']); - $this->assertEquals(1, \count($indexesProject3['body']['indexes'])); - - $indexesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject4['body']['total']); - $this->assertEquals(1, \count($indexesProject4['body']['indexes'])); - - // Attempt to read cross-type resources - $collectionProject2WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject2WithProject1Key['headers']['status-code']); - - $collectionProject1WithProject2Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject1WithProject2Key['headers']['status-code']); - - // Attempt to read cross-tenant resources - $collectionProject3WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject3WithProject1Key['headers']['status-code']); - - $collectionProject1WithProject3Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject1WithProject3Key['headers']['status-code']); - - // Assert that shared project resources can have the same ID as they're unique on tenant + ID not just ID - $collection5 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'name' => 'Amazing Collection', - ]); - - $this->assertEquals(201, $collection5['headers']['status-code']); - - // Assert that users across projects on shared tables can have the same email as they're unique on tenant + email not just email - $user1 = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'userId' => 'user', - 'email' => 'test@appwrite.io', - 'password' => 'password', - 'name' => 'Test User', - ]); - - $this->assertEquals(201, $user1['headers']['status-code']); - - $user2 = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'userId' => 'user', - 'email' => 'test@appwrite.io', - 'password' => 'password', - 'name' => 'Test User', - ]); - - $this->assertEquals(201, $user2['headers']['status-code']); - } } From bbb4b0bc12d6e0a0441c2417604cd83ba4b16302 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 20:29:25 +1200 Subject: [PATCH 19/45] Remove shared table headers --- app/controllers/general.php | 4 ++-- tests/e2e/General/HTTPTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index f1be7bd614..3e243a90d3 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -580,7 +580,7 @@ App::init() ->addHeader('Server', 'Appwrite') ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $refDomain) ->addHeader('Access-Control-Allow-Credentials', 'true'); @@ -631,7 +631,7 @@ App::options() $response ->addHeader('Server', 'Appwrite') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $origin) ->addHeader('Access-Control-Allow-Credentials', 'true') diff --git a/tests/e2e/General/HTTPTest.php b/tests/e2e/General/HTTPTest.php index 0bb5ca4650..92bc52561c 100644 --- a/tests/e2e/General/HTTPTest.php +++ b/tests/e2e/General/HTTPTest.php @@ -31,7 +31,7 @@ class HTTPTest extends Scope $this->assertEquals(204, $response['headers']['status-code']); $this->assertEquals('Appwrite', $response['headers']['server']); $this->assertEquals('GET, POST, PUT, PATCH, DELETE', $response['headers']['access-control-allow-methods']); - $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); + $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); $this->assertEquals('X-Appwrite-Session, X-Fallback-Cookies', $response['headers']['access-control-expose-headers']); $this->assertEquals('http://localhost', $response['headers']['access-control-allow-origin']); $this->assertEquals('true', $response['headers']['access-control-allow-credentials']); From d4db55ab7755375d4363b2cef69058527c94781c Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 29 May 2024 18:11:58 +0900 Subject: [PATCH 20/45] Fix failed queue param in failed jobs --- app/controllers/api/health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 4b4ce8f307..f4581df8e4 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -852,7 +852,7 @@ App::get('/v1/health/queue/failed/:name') Event::FUNCTIONS_QUEUE_NAME, Event::USAGE_QUEUE_NAME, Event::USAGE_DUMP_QUEUE_NAME, - Event::WEBHOOK_CLASS_NAME, + Event::WEBHOOK_QUEUE_NAME, Event::CERTIFICATES_QUEUE_NAME, Event::BUILDS_QUEUE_NAME, Event::MESSAGING_QUEUE_NAME, From 065b5f4858201e93854cd73550d17c9467056abf Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 30 May 2024 16:07:11 +0300 Subject: [PATCH 21/45] test --- composer.json | 2 +- composer.lock | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 205fe308f0..1e60d87bc6 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "utopia-php/cache": "0.9.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.49.*", + "utopia-php/database": "dev-main as 0.49.10", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index 8acbbed541..0c9e96e2e1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "53996479cd4ba0c73dbc72d46b240be0", + "content-hash": "b37a830efbb0467d058a640b289a0a91", "packages": [ { "name": "adhocore/jwt", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.10", + "version": "dev-main", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec" + "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/216209121bc97a2010f67a39c561fafe1e936bec", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec", + "url": "https://api.github.com/repos/utopia-php/database/zipball/4f4b35d99ecdee971c3042279bb1ac8264825030", + "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030", "shasum": "" }, "require": { @@ -1749,6 +1749,7 @@ "swoole/ide-helper": "4.8.0", "utopia-php/cli": "^0.14.0" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -1769,9 +1770,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.10" + "source": "https://github.com/utopia-php/database/tree/main" }, - "time": "2024-05-20T02:14:20+00:00" + "time": "2024-05-30T12:40:27+00:00" }, { "name": "utopia-php/domains", @@ -5587,9 +5588,18 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "dev-main", + "alias": "0.49.10", + "alias_normalized": "0.49.10.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/database": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -5613,5 +5623,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } From c6a520909e0b41d39c6e5f7afc99a65324324065 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:23:15 +0100 Subject: [PATCH 22/45] feat: support twilio messaging service sid --- composer.json | 2 +- composer.lock | 14 +++++++------- src/Appwrite/Platform/Workers/Messaging.php | 18 +++++++++++++----- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 1e60d87bc6..3c34ddbfbb 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", - "utopia-php/messaging": "0.11.*", + "utopia-php/messaging": "0.12.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.5.*", diff --git a/composer.lock b/composer.lock index 0c9e96e2e1..a05931eb63 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b37a830efbb0467d058a640b289a0a91", + "content-hash": "20844ba2607c2746ee92e3b9474086ab", "packages": [ { "name": "adhocore/jwt", @@ -2120,16 +2120,16 @@ }, { "name": "utopia-php/messaging", - "version": "0.11.0", + "version": "0.12.0", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "b499c3ad11af711c28252c62d83f24e6106a2154" + "reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/b499c3ad11af711c28252c62d83f24e6106a2154", - "reference": "b499c3ad11af711c28252c62d83f24e6106a2154", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/6e466d3511981291843c6ebf9ce3f44fc75e37b0", + "reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0", "shasum": "" }, "require": { @@ -2165,9 +2165,9 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.11.0" + "source": "https://github.com/utopia-php/messaging/tree/0.12.0" }, - "time": "2024-05-08T17:10:02+00:00" + "time": "2024-05-30T14:58:25+00:00" }, { "name": "utopia-php/migration", diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 19d2c5a0fe..6f642fabb7 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -399,7 +399,10 @@ class Messaging extends Action 'credentials' => match ($host) { 'twilio' => [ 'accountSid' => $user, - 'authToken' => $password + 'authToken' => $password, + // Twilio Messaging Service SIDs always start with MG + // https://www.twilio.com/docs/messaging/services + 'messagingServiceSid' => \str_starts_with($from, 'MG') ? $from : null ], 'textmagic' => [ 'username' => $user, @@ -420,9 +423,14 @@ class Messaging extends Action ], default => null }, - 'options' => [ - 'from' => $from - ] + 'options' => match ($host) { + 'twilio' => [ + 'from' => \str_starts_with($from, 'MG') ? null : $from + ], + default => [ + 'from' => $from + ] + } ]); $adapter = $this->getSmsAdapter($provider); @@ -465,7 +473,7 @@ class Messaging extends Action return match ($provider->getAttribute('provider')) { 'mock' => new Mock('username', 'password'), - 'twilio' => new Twilio($credentials['accountSid'], $credentials['authToken']), + 'twilio' => new Twilio($credentials['accountSid'], $credentials['authToken'], null, isset($credentials['messagingServiceSid']) ? $credentials['messagingServiceSid'] : null), 'textmagic' => new TextMagic($credentials['username'], $credentials['apiKey']), 'telesign' => new Telesign($credentials['customerId'], $credentials['apiKey']), 'msg91' => new Msg91($credentials['senderId'], $credentials['authKey'], $credentials['templateId']), From 72cca45d6d6d714398b75aaf2832faf7fa82dad1 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:34:43 +0100 Subject: [PATCH 23/45] feat: use param instead --- src/Appwrite/Platform/Workers/Messaging.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 6f642fabb7..a58f2e12ba 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -400,9 +400,7 @@ class Messaging extends Action 'twilio' => [ 'accountSid' => $user, 'authToken' => $password, - // Twilio Messaging Service SIDs always start with MG - // https://www.twilio.com/docs/messaging/services - 'messagingServiceSid' => \str_starts_with($from, 'MG') ? $from : null + 'messagingServiceSid' => $smsDSN->getParam('messagingServiceSid') ?? null ], 'textmagic' => [ 'username' => $user, @@ -425,7 +423,7 @@ class Messaging extends Action }, 'options' => match ($host) { 'twilio' => [ - 'from' => \str_starts_with($from, 'MG') ? null : $from + 'from' => $smsDSN->getParam('messagingServiceSid') ? null : $from ], default => [ 'from' => $from From ab4401992c460489d8f1e645d26592cd4caae404 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:36:05 +0100 Subject: [PATCH 24/45] Revert "feat: use param instead" This reverts commit 72cca45d6d6d714398b75aaf2832faf7fa82dad1. --- src/Appwrite/Platform/Workers/Messaging.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index a58f2e12ba..6f642fabb7 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -400,7 +400,9 @@ class Messaging extends Action 'twilio' => [ 'accountSid' => $user, 'authToken' => $password, - 'messagingServiceSid' => $smsDSN->getParam('messagingServiceSid') ?? null + // Twilio Messaging Service SIDs always start with MG + // https://www.twilio.com/docs/messaging/services + 'messagingServiceSid' => \str_starts_with($from, 'MG') ? $from : null ], 'textmagic' => [ 'username' => $user, @@ -423,7 +425,7 @@ class Messaging extends Action }, 'options' => match ($host) { 'twilio' => [ - 'from' => $smsDSN->getParam('messagingServiceSid') ? null : $from + 'from' => \str_starts_with($from, 'MG') ? null : $from ], default => [ 'from' => $from From e91a532e743bc195ebd40d6fe40c48049df1d3bb Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 30 May 2024 18:46:21 +0300 Subject: [PATCH 25/45] Database tag --- composer.json | 2 +- composer.lock | 20 +++++--------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/composer.json b/composer.json index 1e60d87bc6..205fe308f0 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "utopia-php/cache": "0.9.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-main as 0.49.10", + "utopia-php/database": "0.49.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index 0c9e96e2e1..8119cf4343 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b37a830efbb0467d058a640b289a0a91", + "content-hash": "53996479cd4ba0c73dbc72d46b240be0", "packages": [ { "name": "adhocore/jwt", @@ -1719,7 +1719,7 @@ }, { "name": "utopia-php/database", - "version": "dev-main", + "version": "0.49.11", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", @@ -1749,7 +1749,6 @@ "swoole/ide-helper": "4.8.0", "utopia-php/cli": "^0.14.0" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -1770,7 +1769,7 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/main" + "source": "https://github.com/utopia-php/database/tree/0.49.11" }, "time": "2024-05-30T12:40:27+00:00" }, @@ -5588,18 +5587,9 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [ - { - "package": "utopia-php/database", - "version": "dev-main", - "alias": "0.49.10", - "alias_normalized": "0.49.10.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/database": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 61336be50db635bdccf9dfd003101e71b70ac5a2 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:51:48 +0100 Subject: [PATCH 26/45] doc: update _APP_SMS_FROM --- app/config/variables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/variables.php b/app/config/variables.php index b61a267785..77e8a36763 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -450,7 +450,7 @@ return [ ], [ 'name' => '_APP_SMS_FROM', - 'description' => 'Phone number used for sending out messages. Must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789).', + 'description' => 'Phone number used for sending out messages. If using Twilio, this may be a Messaging Service SID, starting with MG. Otherwise, the number must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789). ', 'introduction' => '0.15.0', 'default' => '', 'required' => false, From e28224976abec4ec832a13d5aa2d29c2c35ba78c Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 2 Jun 2024 16:17:11 +0300 Subject: [PATCH 27/45] refactor redis cache --- composer.json | 4 ++-- composer.lock | 58 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index 205fe308f0..5ea7a0952b 100644 --- a/composer.json +++ b/composer.json @@ -47,10 +47,10 @@ "utopia-php/abuse": "0.37.*", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.39.*", - "utopia-php/cache": "0.9.*", + "utopia-php/cache": "dev-refactor-redis-cache as 0.9.1", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.49.*", + "utopia-php/database": "dev-refactor-cache-flow as 0.49.10", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index 8acbbed541..dd9d5e263d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "53996479cd4ba0c73dbc72d46b240be0", + "content-hash": "42f081ea081021d2f2734fde998ebae5", "packages": [ { "name": "adhocore/jwt", @@ -1569,16 +1569,16 @@ }, { "name": "utopia-php/cache", - "version": "0.9.1", + "version": "dev-refactor-redis-cache", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6" + "reference": "91166f3048af153b48bf7008415fe82785398970" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/552b4c554bb14d0c529631ce304cdf4a2b9d06a6", - "reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/91166f3048af153b48bf7008415fe82785398970", + "reference": "91166f3048af153b48bf7008415fe82785398970", "shasum": "" }, "require": { @@ -1613,9 +1613,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.9.1" + "source": "https://github.com/utopia-php/cache/tree/refactor-redis-cache" }, - "time": "2024-03-19T17:07:20+00:00" + "time": "2024-06-02T10:08:18+00:00" }, { "name": "utopia-php/cli", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.10", + "version": "dev-refactor-cache-flow", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec" + "reference": "13f4729eb2f13fe4b8db2be3c12ceae32489b4e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/216209121bc97a2010f67a39c561fafe1e936bec", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec", + "url": "https://api.github.com/repos/utopia-php/database/zipball/13f4729eb2f13fe4b8db2be3c12ceae32489b4e5", + "reference": "13f4729eb2f13fe4b8db2be3c12ceae32489b4e5", "shasum": "" }, "require": { @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.10" + "source": "https://github.com/utopia-php/database/tree/refactor-cache-flow" }, - "time": "2024-05-20T02:14:20+00:00" + "time": "2024-06-02T11:00:00+00:00" }, { "name": "utopia-php/domains", @@ -3824,16 +3824,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.0", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { @@ -3865,9 +3865,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2024-05-06T12:04:23+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5587,9 +5587,25 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/cache", + "version": "dev-refactor-redis-cache", + "alias": "0.9.1", + "alias_normalized": "0.9.1.0" + }, + { + "package": "utopia-php/database", + "version": "dev-refactor-cache-flow", + "alias": "0.49.10", + "alias_normalized": "0.49.10.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/cache": 20, + "utopia-php/database": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From a823bca463a883f95e78a8ff14cbddad638922cf Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 4 Jun 2024 08:04:51 +0000 Subject: [PATCH 28/45] update platform --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 51ba1980d2..bd63ae0ed8 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "utopia-php/messaging": "0.12.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", - "utopia-php/platform": "0.6.*", + "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", "utopia-php/preloader": "0.2.*", "utopia-php/queue": "0.7.*", diff --git a/composer.lock b/composer.lock index 901465a59d..2b3ea5a8fe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fd1d23f289c62d5258bee977f59adaca", + "content-hash": "0695c0e87cc2243a1c28dbed968bc454", "packages": [ { "name": "adhocore/jwt", @@ -2327,16 +2327,16 @@ }, { "name": "utopia-php/platform", - "version": "0.6.1", + "version": "0.7.0", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "48910f25a9746ed35e8c6952ac1f53ceef0213cb" + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/48910f25a9746ed35e8c6952ac1f53ceef0213cb", - "reference": "48910f25a9746ed35e8c6952ac1f53ceef0213cb", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", "shasum": "" }, "require": { @@ -2371,9 +2371,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.6.1" + "source": "https://github.com/utopia-php/platform/tree/0.7.0" }, - "time": "2024-04-08T05:15:31+00:00" + "time": "2024-05-08T17:00:55+00:00" }, { "name": "utopia-php/pools", From 5b3a3d5bf965d9e76947c9191a909fa1010fbd7b Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 4 Jun 2024 20:10:45 +1200 Subject: [PATCH 29/45] Add flaky test retry --- tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 119c1a2223..966f948ce6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\Functions; +use Appwrite\Tests\Retry; use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; @@ -42,6 +43,7 @@ class FunctionsCustomClientTest extends Scope return []; } + #[Retry(count: 2)] public function testCreateExecution(): array { /** From e2c6c6108313d955d519a5abcc25bfe36228351c Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 5 Jun 2024 20:40:14 +0300 Subject: [PATCH 30/45] composer --- composer.json | 4 ++-- composer.lock | 62 +++++++++++++++++++-------------------------------- 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/composer.json b/composer.json index 5ea7a0952b..c847612f65 100644 --- a/composer.json +++ b/composer.json @@ -47,10 +47,10 @@ "utopia-php/abuse": "0.37.*", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.39.*", - "utopia-php/cache": "dev-refactor-redis-cache as 0.9.1", + "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-refactor-cache-flow as 0.49.10", + "utopia-php/database": "0.49.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index dd9d5e263d..836ddda152 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "42f081ea081021d2f2734fde998ebae5", + "content-hash": "44dc3f42d5df8bab8d3e45ff631f384d", "packages": [ { "name": "adhocore/jwt", @@ -1569,16 +1569,16 @@ }, { "name": "utopia-php/cache", - "version": "dev-refactor-redis-cache", + "version": "0.10.0", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "91166f3048af153b48bf7008415fe82785398970" + "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/91166f3048af153b48bf7008415fe82785398970", - "reference": "91166f3048af153b48bf7008415fe82785398970", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/313bcdfbb166f75c2c205a59d1467cead63a9626", + "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626", "shasum": "" }, "require": { @@ -1613,9 +1613,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/refactor-redis-cache" + "source": "https://github.com/utopia-php/cache/tree/0.10.0" }, - "time": "2024-06-02T10:08:18+00:00" + "time": "2024-06-05T16:40:43+00:00" }, { "name": "utopia-php/cli", @@ -1719,23 +1719,23 @@ }, { "name": "utopia-php/database", - "version": "dev-refactor-cache-flow", + "version": "0.49.12", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "13f4729eb2f13fe4b8db2be3c12ceae32489b4e5" + "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/13f4729eb2f13fe4b8db2be3c12ceae32489b4e5", - "reference": "13f4729eb2f13fe4b8db2be3c12ceae32489b4e5", + "url": "https://api.github.com/repos/utopia-php/database/zipball/45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", + "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", "shasum": "" }, "require": { "ext-mbstring": "*", "ext-pdo": "*", "php": ">=8.0", - "utopia-php/cache": "0.9.*", + "utopia-php/cache": "0.10.*", "utopia-php/framework": "0.33.*", "utopia-php/mongo": "0.3.*" }, @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/refactor-cache-flow" + "source": "https://github.com/utopia-php/database/tree/0.49.12" }, - "time": "2024-06-02T11:00:00+00:00" + "time": "2024-06-05T16:52:59+00:00" }, { "name": "utopia-php/domains", @@ -2755,22 +2755,22 @@ }, { "name": "utopia-php/vcs", - "version": "0.6.6", + "version": "0.6.7", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4" + "reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/e538264cfee5e3efdfe1771efba04750cf20b2c4", - "reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974", + "reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", - "utopia-php/cache": "^0.9.0", + "utopia-php/cache": "^0.10.0", "utopia-php/framework": "0.*.*" }, "require-dev": { @@ -2798,9 +2798,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.6.6" + "source": "https://github.com/utopia-php/vcs/tree/0.6.7" }, - "time": "2024-05-17T09:36:30+00:00" + "time": "2024-06-05T17:38:29+00:00" }, { "name": "utopia-php/websocket", @@ -5587,25 +5587,9 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [ - { - "package": "utopia-php/cache", - "version": "dev-refactor-redis-cache", - "alias": "0.9.1", - "alias_normalized": "0.9.1.0" - }, - { - "package": "utopia-php/database", - "version": "dev-refactor-cache-flow", - "alias": "0.49.10", - "alias_normalized": "0.49.10.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/cache": 20, - "utopia-php/database": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From f06e19d8fa194ec6f0a67a6ad3ff0a17c614af73 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 5 Jun 2024 20:52:35 +0300 Subject: [PATCH 31/45] composer --- composer.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index 836ddda152..929765b74a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "44dc3f42d5df8bab8d3e45ff631f384d", + "content-hash": "9ba1190efa21ae307532896397b3228d", "packages": [ { "name": "adhocore/jwt", @@ -2119,16 +2119,16 @@ }, { "name": "utopia-php/messaging", - "version": "0.11.0", + "version": "0.12.0", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "b499c3ad11af711c28252c62d83f24e6106a2154" + "reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/b499c3ad11af711c28252c62d83f24e6106a2154", - "reference": "b499c3ad11af711c28252c62d83f24e6106a2154", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/6e466d3511981291843c6ebf9ce3f44fc75e37b0", + "reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0", "shasum": "" }, "require": { @@ -2164,9 +2164,9 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.11.0" + "source": "https://github.com/utopia-php/messaging/tree/0.12.0" }, - "time": "2024-05-08T17:10:02+00:00" + "time": "2024-05-30T14:58:25+00:00" }, { "name": "utopia-php/migration", From ff6efc28557754e3b93a4f8f0435b18ad7ab1aff Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 6 Jun 2024 00:11:56 +0530 Subject: [PATCH 32/45] Revert "Feat remove random shared tables" --- .github/workflows/tests.yml | 3 - app/cli.php | 4 +- app/controllers/api/projects.php | 60 ++- app/controllers/general.php | 4 +- app/init.php | 7 +- app/realtime.php | 2 +- app/worker.php | 6 +- docker-compose.yml | 40 +- src/Appwrite/Platform/Workers/Deletes.php | 6 +- tests/e2e/General/HTTPTest.php | 2 +- .../Functions/FunctionsCustomClientTest.php | 2 - .../Projects/ProjectsConsoleClientTest.php | 501 ++++++++++++++++++ 12 files changed, 596 insertions(+), 41 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7bc39392ef..2cc4c700f7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -145,6 +145,3 @@ jobs: - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug - - - name: Run ${{matrix.service}} Shared Tables Tests - run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug diff --git a/app/cli.php b/app/cli.php index 69d4c1c5a8..da7d23c18d 100644 --- a/app/cli.php +++ b/app/cli.php @@ -109,7 +109,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -133,7 +133,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 91f19a2358..f872ef311b 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -111,8 +111,35 @@ App::post('/v1/projects') $projectId = ($projectId == 'unique()') ? ID::unique() : $projectId; + $backups['database_db_fra1_v14x_02'] = ['from' => '03:00', 'to' => '05:00']; + $backups['database_db_fra1_v14x_03'] = ['from' => '00:00', 'to' => '02:00']; + $backups['database_db_fra1_v14x_04'] = ['from' => '00:00', 'to' => '02:00']; + $backups['database_db_fra1_v14x_05'] = ['from' => '00:00', 'to' => '02:00']; + $backups['database_db_fra1_v14x_06'] = ['from' => '00:00', 'to' => '02:00']; + $backups['database_db_fra1_v14x_07'] = ['from' => '00:00', 'to' => '02:00']; + $databases = Config::getParam('pools-database', []); + /** + * Remove databases from the list that are currently undergoing an backup + */ + if (count($databases) > 1) { + $now = new \DateTime(); + + foreach ($databases as $index => $database) { + if (empty($backups[$database])) { + continue; + } + $backup = $backups[$database]; + $from = \DateTime::createFromFormat('H:i', $backup['from']); + $to = \DateTime::createFromFormat('H:i', $backup['to']); + if ($now >= $from && $now <= $to) { + unset($databases[$index]); + break; + } + } + } + $databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE'); $index = \array_search($databaseOverride, $databases); if ($index !== false) { @@ -125,12 +152,37 @@ App::post('/v1/projects') throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project."); } - // TODO: Temporary until all projects are using shared tables. - if ($dsn === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + // TODO: 1 in 5 projects use shared tables. Temporary until all projects are using shared tables. + if ( + ( + !\mt_rand(0, 4) + && System::getEnv('_APP_DATABASE_SHARED_TABLES', 'enabled') === 'enabled' + && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' + ) || + ( + $dsn === DATABASE_SHARED_TABLES + ) + ) { $schema = 'appwrite'; $database = 'appwrite'; $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); - $dsn = $schema . '://' . System::getEnv('_APP_DATABASE_SHARED_TABLES', '') . '?database=' . $database; + $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; + + if (!empty($namespace)) { + $dsn .= '&namespace=' . $namespace; + } + } + + // TODO: Allow overriding in development mode. Temporary until all projects are using shared tables. + if ( + App::isDevelopment() + && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' + && $request->getHeader('x-appwrited-share-tables', false) + ) { + $schema = 'appwrite'; + $database = 'appwrite'; + $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); + $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; if (!empty($namespace)) { $dsn .= '&namespace=' . $namespace; @@ -184,7 +236,7 @@ App::post('/v1/projects') $adapter = $pools->get($dsn->getHost())->pop()->getResource(); $dbForProject = new Database($adapter, $cache); - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $dbForProject ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/controllers/general.php b/app/controllers/general.php index 92ddec58f5..15ba10da36 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -584,7 +584,7 @@ App::init() ->addHeader('Server', 'Appwrite') ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $refDomain) ->addHeader('Access-Control-Allow-Credentials', 'true'); @@ -635,7 +635,7 @@ App::options() $response ->addHeader('Server', 'Appwrite') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $origin) ->addHeader('Access-Control-Allow-Credentials', 'true') diff --git a/app/init.php b/app/init.php index a86156c750..6df2c02908 100644 --- a/app/init.php +++ b/app/init.php @@ -143,6 +143,9 @@ const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite'; const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1'; const APP_HOSTNAME_INTERNAL = 'appwrite'; +// Databases +const DATABASE_SHARED_TABLES = 'database_db_fra1_self_hosted_16_0'; + // Database Reconnect const DATABASE_RECONNECT_SLEEP = 2; const DATABASE_RECONNECT_MAX_ATTEMPTS = 10; @@ -1335,7 +1338,7 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForConsole, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -1388,7 +1391,7 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, ->setMetadata('project', $project->getId()) ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS); - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/realtime.php b/app/realtime.php index cde4327417..2904b1db9c 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -92,7 +92,7 @@ if (!function_exists("getProjectDB")) { $database = new Database($adapter, getCache()); - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/worker.php b/app/worker.php index 314fc65b8e..60358ad6b2 100644 --- a/app/worker.php +++ b/app/worker.php @@ -93,7 +93,7 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -126,7 +126,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -150,7 +150,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/docker-compose.yml b/docker-compose.yml index b86af1c12b..b1e30a1e07 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -189,7 +189,6 @@ services: - _APP_CONSOLE_COUNTRIES_DENYLIST - _APP_EXPERIMENT_LOGGING_PROVIDER - _APP_EXPERIMENT_LOGGING_CONFIG - - _APP_DATABASE_SHARED_TABLES appwrite-realtime: entrypoint: realtime @@ -239,7 +238,6 @@ services: - _APP_USAGE_STATS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - - _APP_DATABASE_SHARED_TABLES appwrite-worker-audits: entrypoint: worker-audits @@ -269,7 +267,6 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - - _APP_DATABASE_SHARED_TABLES appwrite-worker-webhooks: entrypoint: worker-webhooks @@ -302,7 +299,6 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_WEBHOOK_MAX_FAILED_ATTEMPTS - - _APP_DATABASE_SHARED_TABLES appwrite-worker-deletes: entrypoint: worker-deletes @@ -360,7 +356,6 @@ services: - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST - - _APP_DATABASE_SHARED_TABLES appwrite-worker-databases: entrypoint: worker-databases @@ -392,7 +387,6 @@ services: - _APP_LOGGING_CONFIG - _APP_WORKERS_NUM - _APP_QUEUE_NAME - - _APP_DATABASE_SHARED_TABLES appwrite-worker-builds: entrypoint: worker-builds @@ -458,7 +452,6 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET - - _APP_DATABASE_SHARED_TABLES appwrite-worker-certificates: entrypoint: worker-certificates @@ -494,7 +487,6 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - - _APP_DATABASE_SHARED_TABLES appwrite-worker-functions: entrypoint: worker-functions @@ -534,7 +526,6 @@ services: - _APP_DOCKER_HUB_PASSWORD - _APP_LOGGING_CONFIG - _APP_LOGGING_PROVIDER - - _APP_DATABASE_SHARED_TABLES appwrite-worker-mails: entrypoint: worker-mails @@ -569,7 +560,6 @@ services: - _APP_LOGGING_CONFIG - _APP_DOMAIN - _APP_OPTIONS_FORCE_HTTPS - - _APP_DATABASE_SHARED_TABLES appwrite-worker-messaging: entrypoint: worker-messaging @@ -624,7 +614,6 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET - - _APP_DATABASE_SHARED_TABLES appwrite-worker-migrations: entrypoint: worker-migrations @@ -660,7 +649,6 @@ services: - _APP_LOGGING_CONFIG - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - - _APP_DATABASE_SHARED_TABLES appwrite-task-maintenance: entrypoint: maintenance @@ -698,7 +686,6 @@ services: - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY - _APP_MAINTENANCE_RETENTION_SCHEDULES - _APP_MAINTENANCE_DELAY - - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage: entrypoint: worker-usage @@ -730,7 +717,6 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL - - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage-dump: entrypoint: worker-usage-dump @@ -762,7 +748,6 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL - - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-functions: entrypoint: schedule-functions @@ -790,7 +775,6 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-messages: entrypoint: schedule-messages @@ -818,7 +802,6 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_DATABASE_SHARED_TABLES appwrite-assistant: container_name: appwrite-assistant @@ -917,7 +900,20 @@ services: - MYSQL_USER=${_APP_DB_USER} - MYSQL_PASSWORD=${_APP_DB_PASS} - MARIADB_AUTO_UPGRADE=1 - command: "mysqld --innodb-flush-method=fsync" + command: "mysqld --innodb-flush-method=fsync" # add ' --query_cache_size=0' for DB tests + # command: mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bu && mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bu + + # smtp: + # image: appwrite/smtp:1.2.0 + # container_name: appwrite-smtp + # restart: unless-stopped + # networks: + # - appwrite + # environment: + # - LOCAL_DOMAINS=@ + # - RELAY_FROM_HOSTS=192.168.0.0/16 ; *.yourdomain.com + # - SMARTHOST_HOST=smtp + # - SMARTHOST_PORT=587 redis: image: redis:7.2.4-alpine @@ -935,6 +931,14 @@ services: volumes: - appwrite-redis:/data:rw + # clamav: + # image: appwrite/clamav:1.2.0 + # container_name: appwrite-clamav + # networks: + # - appwrite + # volumes: + # - appwrite-uploads:/storage/uploads + # Dev Tools Start ------------------------------------------------------------------------------------------ # # The Appwrite Team uses the following tools to help debug, monitor and diagnose the Appwrite stack diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index d54f3f5079..49b41da495 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -498,14 +498,14 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { - if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { + if ($dsn->getHost() !== DATABASE_SHARED_TABLES || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } } - if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { $collectionsIds = \array_map(fn ($collection) => $collection->getId(), $collections); if (empty(\array_diff($collectionsIds, $projectCollectionIds))) { @@ -554,7 +554,7 @@ class Deletes extends Action ], $dbForConsole); // Delete metadata table - if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { + if ($dsn->getHost() !== DATABASE_SHARED_TABLES) { $dbForProject->deleteCollection('_metadata'); } else { $this->deleteByGroup('_metadata', [], $dbForProject); diff --git a/tests/e2e/General/HTTPTest.php b/tests/e2e/General/HTTPTest.php index 92bc52561c..0bb5ca4650 100644 --- a/tests/e2e/General/HTTPTest.php +++ b/tests/e2e/General/HTTPTest.php @@ -31,7 +31,7 @@ class HTTPTest extends Scope $this->assertEquals(204, $response['headers']['status-code']); $this->assertEquals('Appwrite', $response['headers']['server']); $this->assertEquals('GET, POST, PUT, PATCH, DELETE', $response['headers']['access-control-allow-methods']); - $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); + $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); $this->assertEquals('X-Appwrite-Session, X-Fallback-Cookies', $response['headers']['access-control-expose-headers']); $this->assertEquals('http://localhost', $response['headers']['access-control-allow-origin']); $this->assertEquals('true', $response['headers']['access-control-allow-credentials']); diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 966f948ce6..119c1a2223 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -2,7 +2,6 @@ namespace Tests\E2E\Services\Functions; -use Appwrite\Tests\Retry; use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; @@ -43,7 +42,6 @@ class FunctionsCustomClientTest extends Scope return []; } - #[Retry(count: 2)] public function testCreateExecution(): array { /** diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 2af0c8f1cc..8cdd325501 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -9,6 +9,7 @@ use Tests\E2E\General\UsageTest; use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; +use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; @@ -3493,4 +3494,504 @@ class ProjectsConsoleClientTest extends Scope return $data; } + + public function testTenantIsolation(): void + { + // Create a team and a project + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Amazing Team', + ]); + + $teamId = $team['body']['$id']; + + // Project-level isolation + $project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-shared-tables' => false + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Amazing Project', + 'teamId' => $teamId, + 'region' => 'default' + ]); + + // Application level isolation (shared tables) + $project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-shared-tables' => true + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Amazing Project', + 'teamId' => $teamId, + 'region' => 'default' + ]); + + // Project-level isolation + $project3 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-shared-tables' => false + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Amazing Project', + 'teamId' => $teamId, + 'region' => 'default' + ]); + + // Application level isolation (shared tables) + $project4 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-shared-tables' => true + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Amazing Project', + 'teamId' => $teamId, + 'region' => 'default' + ]); + + // Create and API key in each project + $key1 = $this->client->call(Client::METHOD_POST, '/projects/' . $project1['body']['$id'] . '/keys', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'Key Test', + 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], + ]); + + $key2 = $this->client->call(Client::METHOD_POST, '/projects/' . $project2['body']['$id'] . '/keys', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'Key Test', + 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], + ]); + + $key3 = $this->client->call(Client::METHOD_POST, '/projects/' . $project3['body']['$id'] . '/keys', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'Key Test', + 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], + ]); + + $key4 = $this->client->call(Client::METHOD_POST, '/projects/' . $project4['body']['$id'] . '/keys', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'Key Test', + 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], + ]); + + // Create a database in each project + $database1 = $this->client->call(Client::METHOD_POST, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ], [ + 'databaseId' => ID::unique(), + 'name' => 'Amazing Database', + ]); + + $database2 = $this->client->call(Client::METHOD_POST, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ], [ + 'databaseId' => ID::unique(), + 'name' => 'Amazing Database', + ]); + + $database3 = $this->client->call(Client::METHOD_POST, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ], [ + 'databaseId' => ID::unique(), + 'name' => 'Amazing Database', + ]); + + $database4 = $this->client->call(Client::METHOD_POST, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ], [ + 'databaseId' => ID::unique(), + 'name' => 'Amazing Database', + ]); + + // Create a collection in each project + $collection1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ], [ + 'databaseId' => $database1['body']['$id'], + 'collectionId' => ID::unique(), + 'name' => 'Amazing Collection', + ]); + + $collection2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ], [ + 'databaseId' => $database2['body']['$id'], + 'collectionId' => ID::unique(), + 'name' => 'Amazing Collection', + ]); + + $collection3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ], [ + 'databaseId' => $database3['body']['$id'], + 'collectionId' => ID::unique(), + 'name' => 'Amazing Collection', + ]); + + $collection4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ], [ + 'databaseId' => $database4['body']['$id'], + 'collectionId' => ID::unique(), + 'name' => 'Amazing Collection', + ]); + + // Create an attribute in each project + $attribute1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes/string', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ], [ + 'databaseId' => $database1['body']['$id'], + 'collectionId' => $collection1['body']['$id'], + 'key' => ID::unique(), + 'size' => 255, + 'required' => true + ]); + + $attribute2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes/string', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ], [ + 'databaseId' => $database2['body']['$id'], + 'collectionId' => $collection2['body']['$id'], + 'key' => ID::unique(), + 'size' => 255, + 'required' => true + ]); + + $attribute3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes/string', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ], [ + 'databaseId' => $database3['body']['$id'], + 'collectionId' => $collection3['body']['$id'], + 'key' => ID::unique(), + 'size' => 255, + 'required' => true + ]); + + $attribute4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes/string', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ], [ + 'databaseId' => $database4['body']['$id'], + 'collectionId' => $collection4['body']['$id'], + 'key' => ID::unique(), + 'size' => 255, + 'required' => true + ]); + + // Wait for attributes + \sleep(2); + + // Create an index in each project + $index1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ], [ + 'databaseId' => $database1['body']['$id'], + 'collectionId' => $collection1['body']['$id'], + 'key' => ID::unique(), + 'type' => Database::INDEX_KEY, + 'attributes' => [$attribute1['body']['key']], + ]); + + $index2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ], [ + 'databaseId' => $database2['body']['$id'], + 'collectionId' => $collection2['body']['$id'], + 'key' => ID::unique(), + 'type' => Database::INDEX_KEY, + 'attributes' => [$attribute2['body']['key']], + ]); + + $index3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ], [ + 'databaseId' => $database3['body']['$id'], + 'collectionId' => $collection3['body']['$id'], + 'key' => ID::unique(), + 'type' => Database::INDEX_KEY, + 'attributes' => [$attribute3['body']['key']], + ]); + + $index4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ], [ + 'databaseId' => $database4['body']['$id'], + 'collectionId' => $collection4['body']['$id'], + 'key' => ID::unique(), + 'type' => Database::INDEX_KEY, + 'attributes' => [$attribute4['body']['key']], + ]); + + // Wait for indexes + \sleep(2); + + // Assert that each project has only 1 database, 1 collection, 1 attribute and 1 index + $databasesProject1 = $this->client->call(Client::METHOD_GET, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ]); + + $this->assertEquals(1, $databasesProject1['body']['total']); + $this->assertEquals(1, \count($databasesProject1['body']['databases'])); + + $databasesProject2 = $this->client->call(Client::METHOD_GET, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ]); + + $this->assertEquals(1, $databasesProject2['body']['total']); + $this->assertEquals(1, \count($databasesProject2['body']['databases'])); + + $databasesProject3 = $this->client->call(Client::METHOD_GET, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ]); + + $this->assertEquals(1, $databasesProject3['body']['total']); + $this->assertEquals(1, \count($databasesProject3['body']['databases'])); + + $databasesProject4 = $this->client->call(Client::METHOD_GET, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ]); + + $this->assertEquals(1, $databasesProject4['body']['total']); + $this->assertEquals(1, \count($databasesProject4['body']['databases'])); + + $collectionsProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ]); + + $this->assertEquals(1, $collectionsProject1['body']['total']); + $this->assertEquals(1, \count($collectionsProject1['body']['collections'])); + + $collectionsProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ]); + + $this->assertEquals(1, $collectionsProject2['body']['total']); + $this->assertEquals(1, \count($collectionsProject2['body']['collections'])); + + $collectionsProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ]); + + $this->assertEquals(1, $collectionsProject3['body']['total']); + $this->assertEquals(1, \count($collectionsProject3['body']['collections'])); + + $collectionsProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ]); + + $this->assertEquals(1, $collectionsProject4['body']['total']); + $this->assertEquals(1, \count($collectionsProject4['body']['collections'])); + + $attributesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ]); + + $this->assertEquals(1, $attributesProject1['body']['total']); + $this->assertEquals(1, \count($attributesProject1['body']['attributes'])); + $this->assertEquals('available', $attributesProject1['body']['attributes'][0]['status']); + + $attributesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ]); + + $this->assertEquals(1, $attributesProject2['body']['total']); + $this->assertEquals(1, \count($attributesProject2['body']['attributes'])); + $this->assertEquals('available', $attributesProject2['body']['attributes'][0]['status']); + + $attributesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ]); + + $this->assertEquals(1, $attributesProject3['body']['total']); + $this->assertEquals(1, \count($attributesProject3['body']['attributes'])); + $this->assertEquals('available', $attributesProject3['body']['attributes'][0]['status']); + + $attributesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ]); + + $this->assertEquals(1, $attributesProject4['body']['total']); + $this->assertEquals(1, \count($attributesProject4['body']['attributes'])); + $this->assertEquals('available', $attributesProject4['body']['attributes'][0]['status']); + + $indexesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ]); + + $this->assertEquals(1, $indexesProject1['body']['total']); + $this->assertEquals(1, \count($indexesProject1['body']['indexes'])); + + $indexesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ]); + + $this->assertEquals(1, $indexesProject2['body']['total']); + $this->assertEquals(1, \count($indexesProject2['body']['indexes'])); + + $indexesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ]); + + $this->assertEquals(1, $indexesProject3['body']['total']); + $this->assertEquals(1, \count($indexesProject3['body']['indexes'])); + + $indexesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ]); + + $this->assertEquals(1, $indexesProject4['body']['total']); + $this->assertEquals(1, \count($indexesProject4['body']['indexes'])); + + // Attempt to read cross-type resources + $collectionProject2WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ]); + + $this->assertEquals(404, $collectionProject2WithProject1Key['headers']['status-code']); + + $collectionProject1WithProject2Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ]); + + $this->assertEquals(404, $collectionProject1WithProject2Key['headers']['status-code']); + + // Attempt to read cross-tenant resources + $collectionProject3WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project1['body']['$id'], + 'x-appwrite-key' => $key1['body']['secret'] + ]); + + $this->assertEquals(404, $collectionProject3WithProject1Key['headers']['status-code']); + + $collectionProject1WithProject3Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project3['body']['$id'], + 'x-appwrite-key' => $key3['body']['secret'] + ]); + + $this->assertEquals(404, $collectionProject1WithProject3Key['headers']['status-code']); + + // Assert that shared project resources can have the same ID as they're unique on tenant + ID not just ID + $collection5 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ], [ + 'databaseId' => $database2['body']['$id'], + 'collectionId' => $collection4['body']['$id'], + 'name' => 'Amazing Collection', + ]); + + $this->assertEquals(201, $collection5['headers']['status-code']); + + // Assert that users across projects on shared tables can have the same email as they're unique on tenant + email not just email + $user1 = $this->client->call(Client::METHOD_POST, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2['body']['$id'], + 'x-appwrite-key' => $key2['body']['secret'] + ], [ + 'userId' => 'user', + 'email' => 'test@appwrite.io', + 'password' => 'password', + 'name' => 'Test User', + ]); + + $this->assertEquals(201, $user1['headers']['status-code']); + + $user2 = $this->client->call(Client::METHOD_POST, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project4['body']['$id'], + 'x-appwrite-key' => $key4['body']['secret'] + ], [ + 'userId' => 'user', + 'email' => 'test@appwrite.io', + 'password' => 'password', + 'name' => 'Test User', + ]); + + $this->assertEquals(201, $user2['headers']['status-code']); + } } From cdf7e1a8dc73020c792510533fecffb3c48299b1 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 5 Jun 2024 22:29:47 +0300 Subject: [PATCH 33/45] composer --- composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index 929765b74a..5ee1aff322 100644 --- a/composer.lock +++ b/composer.lock @@ -1427,16 +1427,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.0", + "version": "0.37.1", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062" + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/2de5c12886cbd516e511e559afdd9e615d871062", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981", + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981", "shasum": "" }, "require": { @@ -1470,9 +1470,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.0" + "source": "https://github.com/utopia-php/abuse/tree/0.37.1" }, - "time": "2024-03-06T21:20:27+00:00" + "time": "2024-06-05T18:03:59+00:00" }, { "name": "utopia-php/analytics", @@ -1522,16 +1522,16 @@ }, { "name": "utopia-php/audit", - "version": "0.39.0", + "version": "0.39.1", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c" + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/f0bc15012e05cc0b9dde012ab27d25f193768a2c", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2", + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2", "shasum": "" }, "require": { @@ -1563,9 +1563,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.0" + "source": "https://github.com/utopia-php/audit/tree/0.39.1" }, - "time": "2024-03-06T21:20:37+00:00" + "time": "2024-06-05T19:28:22+00:00" }, { "name": "utopia-php/cache", From 9e487b8ccf01fd145ebf319c2b7c428c57f351ab Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 6 Jun 2024 20:11:19 +1200 Subject: [PATCH 34/45] Revert "Merge pull request #8237 from appwrite/revert-8193-feat-remove-random-shared-tables" This reverts commit 930ae6ded024ae28b683abbd73babe1b7b9464d2, reversing changes made to 1f6417b1560ae46763fe42ab99b4a77ff5e458e8. --- .github/workflows/tests.yml | 3 + app/cli.php | 4 +- app/controllers/api/projects.php | 60 +-- app/controllers/general.php | 4 +- app/init.php | 7 +- app/realtime.php | 2 +- app/worker.php | 6 +- docker-compose.yml | 40 +- src/Appwrite/Platform/Workers/Deletes.php | 6 +- tests/e2e/General/HTTPTest.php | 2 +- .../Functions/FunctionsCustomClientTest.php | 2 + .../Projects/ProjectsConsoleClientTest.php | 501 ------------------ 12 files changed, 41 insertions(+), 596 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2cc4c700f7..7bc39392ef 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -145,3 +145,6 @@ jobs: - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug + + - name: Run ${{matrix.service}} Shared Tables Tests + run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug diff --git a/app/cli.php b/app/cli.php index da7d23c18d..69d4c1c5a8 100644 --- a/app/cli.php +++ b/app/cli.php @@ -109,7 +109,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -133,7 +133,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index f872ef311b..91f19a2358 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -111,35 +111,8 @@ App::post('/v1/projects') $projectId = ($projectId == 'unique()') ? ID::unique() : $projectId; - $backups['database_db_fra1_v14x_02'] = ['from' => '03:00', 'to' => '05:00']; - $backups['database_db_fra1_v14x_03'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_04'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_05'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_06'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_07'] = ['from' => '00:00', 'to' => '02:00']; - $databases = Config::getParam('pools-database', []); - /** - * Remove databases from the list that are currently undergoing an backup - */ - if (count($databases) > 1) { - $now = new \DateTime(); - - foreach ($databases as $index => $database) { - if (empty($backups[$database])) { - continue; - } - $backup = $backups[$database]; - $from = \DateTime::createFromFormat('H:i', $backup['from']); - $to = \DateTime::createFromFormat('H:i', $backup['to']); - if ($now >= $from && $now <= $to) { - unset($databases[$index]); - break; - } - } - } - $databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE'); $index = \array_search($databaseOverride, $databases); if ($index !== false) { @@ -152,37 +125,12 @@ App::post('/v1/projects') throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project."); } - // TODO: 1 in 5 projects use shared tables. Temporary until all projects are using shared tables. - if ( - ( - !\mt_rand(0, 4) - && System::getEnv('_APP_DATABASE_SHARED_TABLES', 'enabled') === 'enabled' - && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' - ) || - ( - $dsn === DATABASE_SHARED_TABLES - ) - ) { + // TODO: Temporary until all projects are using shared tables. + if ($dsn === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $schema = 'appwrite'; $database = 'appwrite'; $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); - $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; - - if (!empty($namespace)) { - $dsn .= '&namespace=' . $namespace; - } - } - - // TODO: Allow overriding in development mode. Temporary until all projects are using shared tables. - if ( - App::isDevelopment() - && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' - && $request->getHeader('x-appwrited-share-tables', false) - ) { - $schema = 'appwrite'; - $database = 'appwrite'; - $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); - $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; + $dsn = $schema . '://' . System::getEnv('_APP_DATABASE_SHARED_TABLES', '') . '?database=' . $database; if (!empty($namespace)) { $dsn .= '&namespace=' . $namespace; @@ -236,7 +184,7 @@ App::post('/v1/projects') $adapter = $pools->get($dsn->getHost())->pop()->getResource(); $dbForProject = new Database($adapter, $cache); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $dbForProject ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/controllers/general.php b/app/controllers/general.php index 15ba10da36..92ddec58f5 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -584,7 +584,7 @@ App::init() ->addHeader('Server', 'Appwrite') ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $refDomain) ->addHeader('Access-Control-Allow-Credentials', 'true'); @@ -635,7 +635,7 @@ App::options() $response ->addHeader('Server', 'Appwrite') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $origin) ->addHeader('Access-Control-Allow-Credentials', 'true') diff --git a/app/init.php b/app/init.php index 6df2c02908..a86156c750 100644 --- a/app/init.php +++ b/app/init.php @@ -143,9 +143,6 @@ const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite'; const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1'; const APP_HOSTNAME_INTERNAL = 'appwrite'; -// Databases -const DATABASE_SHARED_TABLES = 'database_db_fra1_self_hosted_16_0'; - // Database Reconnect const DATABASE_RECONNECT_SLEEP = 2; const DATABASE_RECONNECT_MAX_ATTEMPTS = 10; @@ -1338,7 +1335,7 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForConsole, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -1391,7 +1388,7 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, ->setMetadata('project', $project->getId()) ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/realtime.php b/app/realtime.php index 2904b1db9c..cde4327417 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -92,7 +92,7 @@ if (!function_exists("getProjectDB")) { $database = new Database($adapter, getCache()); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/worker.php b/app/worker.php index 60358ad6b2..314fc65b8e 100644 --- a/app/worker.php +++ b/app/worker.php @@ -93,7 +93,7 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -126,7 +126,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -150,7 +150,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/docker-compose.yml b/docker-compose.yml index b1e30a1e07..b86af1c12b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -189,6 +189,7 @@ services: - _APP_CONSOLE_COUNTRIES_DENYLIST - _APP_EXPERIMENT_LOGGING_PROVIDER - _APP_EXPERIMENT_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-realtime: entrypoint: realtime @@ -238,6 +239,7 @@ services: - _APP_USAGE_STATS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-audits: entrypoint: worker-audits @@ -267,6 +269,7 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-webhooks: entrypoint: worker-webhooks @@ -299,6 +302,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_WEBHOOK_MAX_FAILED_ATTEMPTS + - _APP_DATABASE_SHARED_TABLES appwrite-worker-deletes: entrypoint: worker-deletes @@ -356,6 +360,7 @@ services: - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST + - _APP_DATABASE_SHARED_TABLES appwrite-worker-databases: entrypoint: worker-databases @@ -387,6 +392,7 @@ services: - _APP_LOGGING_CONFIG - _APP_WORKERS_NUM - _APP_QUEUE_NAME + - _APP_DATABASE_SHARED_TABLES appwrite-worker-builds: entrypoint: worker-builds @@ -452,6 +458,7 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET + - _APP_DATABASE_SHARED_TABLES appwrite-worker-certificates: entrypoint: worker-certificates @@ -487,6 +494,7 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-functions: entrypoint: worker-functions @@ -526,6 +534,7 @@ services: - _APP_DOCKER_HUB_PASSWORD - _APP_LOGGING_CONFIG - _APP_LOGGING_PROVIDER + - _APP_DATABASE_SHARED_TABLES appwrite-worker-mails: entrypoint: worker-mails @@ -560,6 +569,7 @@ services: - _APP_LOGGING_CONFIG - _APP_DOMAIN - _APP_OPTIONS_FORCE_HTTPS + - _APP_DATABASE_SHARED_TABLES appwrite-worker-messaging: entrypoint: worker-messaging @@ -614,6 +624,7 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET + - _APP_DATABASE_SHARED_TABLES appwrite-worker-migrations: entrypoint: worker-migrations @@ -649,6 +660,7 @@ services: - _APP_LOGGING_CONFIG - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET + - _APP_DATABASE_SHARED_TABLES appwrite-task-maintenance: entrypoint: maintenance @@ -686,6 +698,7 @@ services: - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY - _APP_MAINTENANCE_RETENTION_SCHEDULES - _APP_MAINTENANCE_DELAY + - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage: entrypoint: worker-usage @@ -717,6 +730,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage-dump: entrypoint: worker-usage-dump @@ -748,6 +762,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-functions: entrypoint: schedule-functions @@ -775,6 +790,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-messages: entrypoint: schedule-messages @@ -802,6 +818,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_DATABASE_SHARED_TABLES appwrite-assistant: container_name: appwrite-assistant @@ -900,20 +917,7 @@ services: - MYSQL_USER=${_APP_DB_USER} - MYSQL_PASSWORD=${_APP_DB_PASS} - MARIADB_AUTO_UPGRADE=1 - command: "mysqld --innodb-flush-method=fsync" # add ' --query_cache_size=0' for DB tests - # command: mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bu && mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bu - - # smtp: - # image: appwrite/smtp:1.2.0 - # container_name: appwrite-smtp - # restart: unless-stopped - # networks: - # - appwrite - # environment: - # - LOCAL_DOMAINS=@ - # - RELAY_FROM_HOSTS=192.168.0.0/16 ; *.yourdomain.com - # - SMARTHOST_HOST=smtp - # - SMARTHOST_PORT=587 + command: "mysqld --innodb-flush-method=fsync" redis: image: redis:7.2.4-alpine @@ -931,14 +935,6 @@ services: volumes: - appwrite-redis:/data:rw - # clamav: - # image: appwrite/clamav:1.2.0 - # container_name: appwrite-clamav - # networks: - # - appwrite - # volumes: - # - appwrite-uploads:/storage/uploads - # Dev Tools Start ------------------------------------------------------------------------------------------ # # The Appwrite Team uses the following tools to help debug, monitor and diagnose the Appwrite stack diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 49b41da495..d54f3f5079 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -498,14 +498,14 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { - if ($dsn->getHost() !== DATABASE_SHARED_TABLES || !\in_array($collection->getId(), $projectCollectionIds)) { + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $collectionsIds = \array_map(fn ($collection) => $collection->getId(), $collections); if (empty(\array_diff($collectionsIds, $projectCollectionIds))) { @@ -554,7 +554,7 @@ class Deletes extends Action ], $dbForConsole); // Delete metadata table - if ($dsn->getHost() !== DATABASE_SHARED_TABLES) { + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $dbForProject->deleteCollection('_metadata'); } else { $this->deleteByGroup('_metadata', [], $dbForProject); diff --git a/tests/e2e/General/HTTPTest.php b/tests/e2e/General/HTTPTest.php index 0bb5ca4650..92bc52561c 100644 --- a/tests/e2e/General/HTTPTest.php +++ b/tests/e2e/General/HTTPTest.php @@ -31,7 +31,7 @@ class HTTPTest extends Scope $this->assertEquals(204, $response['headers']['status-code']); $this->assertEquals('Appwrite', $response['headers']['server']); $this->assertEquals('GET, POST, PUT, PATCH, DELETE', $response['headers']['access-control-allow-methods']); - $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); + $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); $this->assertEquals('X-Appwrite-Session, X-Fallback-Cookies', $response['headers']['access-control-expose-headers']); $this->assertEquals('http://localhost', $response['headers']['access-control-allow-origin']); $this->assertEquals('true', $response['headers']['access-control-allow-credentials']); diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 119c1a2223..966f948ce6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\Functions; +use Appwrite\Tests\Retry; use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; @@ -42,6 +43,7 @@ class FunctionsCustomClientTest extends Scope return []; } + #[Retry(count: 2)] public function testCreateExecution(): array { /** diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 8cdd325501..2af0c8f1cc 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -9,7 +9,6 @@ use Tests\E2E\General\UsageTest; use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; @@ -3494,504 +3493,4 @@ class ProjectsConsoleClientTest extends Scope return $data; } - - public function testTenantIsolation(): void - { - // Create a team and a project - $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'teamId' => ID::unique(), - 'name' => 'Amazing Team', - ]); - - $teamId = $team['body']['$id']; - - // Project-level isolation - $project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => false - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Application level isolation (shared tables) - $project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => true - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Project-level isolation - $project3 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => false - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Application level isolation (shared tables) - $project4 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => true - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Create and API key in each project - $key1 = $this->client->call(Client::METHOD_POST, '/projects/' . $project1['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key2 = $this->client->call(Client::METHOD_POST, '/projects/' . $project2['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key3 = $this->client->call(Client::METHOD_POST, '/projects/' . $project3['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key4 = $this->client->call(Client::METHOD_POST, '/projects/' . $project4['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - // Create a database in each project - $database1 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database2 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database3 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database4 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - // Create a collection in each project - $collection1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - // Create an attribute in each project - $attribute1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => $collection1['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection2['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => $collection3['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - // Wait for attributes - \sleep(2); - - // Create an index in each project - $index1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => $collection1['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute1['body']['key']], - ]); - - $index2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection2['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute2['body']['key']], - ]); - - $index3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => $collection3['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute3['body']['key']], - ]); - - $index4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute4['body']['key']], - ]); - - // Wait for indexes - \sleep(2); - - // Assert that each project has only 1 database, 1 collection, 1 attribute and 1 index - $databasesProject1 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject1['body']['total']); - $this->assertEquals(1, \count($databasesProject1['body']['databases'])); - - $databasesProject2 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject2['body']['total']); - $this->assertEquals(1, \count($databasesProject2['body']['databases'])); - - $databasesProject3 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject3['body']['total']); - $this->assertEquals(1, \count($databasesProject3['body']['databases'])); - - $databasesProject4 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject4['body']['total']); - $this->assertEquals(1, \count($databasesProject4['body']['databases'])); - - $collectionsProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject1['body']['total']); - $this->assertEquals(1, \count($collectionsProject1['body']['collections'])); - - $collectionsProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject2['body']['total']); - $this->assertEquals(1, \count($collectionsProject2['body']['collections'])); - - $collectionsProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject3['body']['total']); - $this->assertEquals(1, \count($collectionsProject3['body']['collections'])); - - $collectionsProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject4['body']['total']); - $this->assertEquals(1, \count($collectionsProject4['body']['collections'])); - - $attributesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject1['body']['total']); - $this->assertEquals(1, \count($attributesProject1['body']['attributes'])); - $this->assertEquals('available', $attributesProject1['body']['attributes'][0]['status']); - - $attributesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject2['body']['total']); - $this->assertEquals(1, \count($attributesProject2['body']['attributes'])); - $this->assertEquals('available', $attributesProject2['body']['attributes'][0]['status']); - - $attributesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject3['body']['total']); - $this->assertEquals(1, \count($attributesProject3['body']['attributes'])); - $this->assertEquals('available', $attributesProject3['body']['attributes'][0]['status']); - - $attributesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject4['body']['total']); - $this->assertEquals(1, \count($attributesProject4['body']['attributes'])); - $this->assertEquals('available', $attributesProject4['body']['attributes'][0]['status']); - - $indexesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject1['body']['total']); - $this->assertEquals(1, \count($indexesProject1['body']['indexes'])); - - $indexesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject2['body']['total']); - $this->assertEquals(1, \count($indexesProject2['body']['indexes'])); - - $indexesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject3['body']['total']); - $this->assertEquals(1, \count($indexesProject3['body']['indexes'])); - - $indexesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject4['body']['total']); - $this->assertEquals(1, \count($indexesProject4['body']['indexes'])); - - // Attempt to read cross-type resources - $collectionProject2WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject2WithProject1Key['headers']['status-code']); - - $collectionProject1WithProject2Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject1WithProject2Key['headers']['status-code']); - - // Attempt to read cross-tenant resources - $collectionProject3WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject3WithProject1Key['headers']['status-code']); - - $collectionProject1WithProject3Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject1WithProject3Key['headers']['status-code']); - - // Assert that shared project resources can have the same ID as they're unique on tenant + ID not just ID - $collection5 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'name' => 'Amazing Collection', - ]); - - $this->assertEquals(201, $collection5['headers']['status-code']); - - // Assert that users across projects on shared tables can have the same email as they're unique on tenant + email not just email - $user1 = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'userId' => 'user', - 'email' => 'test@appwrite.io', - 'password' => 'password', - 'name' => 'Test User', - ]); - - $this->assertEquals(201, $user1['headers']['status-code']); - - $user2 = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'userId' => 'user', - 'email' => 'test@appwrite.io', - 'password' => 'password', - 'name' => 'Test User', - ]); - - $this->assertEquals(201, $user2['headers']['status-code']); - } } From 131de2ea7a7fd12098ab747a609d478c229f6c25 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 6 Jun 2024 08:35:50 +0000 Subject: [PATCH 35/45] refactor module --- src/Appwrite/Platform/Appwrite.php | 4 ---- src/Appwrite/Platform/Modules/Core.php | 8 ++++++++ src/Appwrite/Platform/Services/Workers.php | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Platform/Appwrite.php b/src/Appwrite/Platform/Appwrite.php index fac55635d3..6b3eb077fa 100644 --- a/src/Appwrite/Platform/Appwrite.php +++ b/src/Appwrite/Platform/Appwrite.php @@ -2,8 +2,6 @@ namespace Appwrite\Platform; -use Appwrite\Platform\Services\Tasks; -use Appwrite\Platform\Services\Workers; use Appwrite\Platform\Modules\Core; use Utopia\Platform\Platform; @@ -12,7 +10,5 @@ class Appwrite extends Platform public function __construct() { parent::__construct(new Core()); - $this->addService('tasks', new Tasks()); - $this->addService('workers', new Workers()); } } diff --git a/src/Appwrite/Platform/Modules/Core.php b/src/Appwrite/Platform/Modules/Core.php index ea73e07690..859ca3b529 100644 --- a/src/Appwrite/Platform/Modules/Core.php +++ b/src/Appwrite/Platform/Modules/Core.php @@ -2,8 +2,16 @@ namespace Appwrite\Platform\Modules; +use Appwrite\Platform\Services\Tasks; +use Appwrite\Platform\Services\Workers; use Utopia\Platform\Module; class Core extends Module { + public function __construct() + { + $this->addService('tasks', new Tasks()); + $this->addService('workers', new Workers()); + } + } diff --git a/src/Appwrite/Platform/Services/Workers.php b/src/Appwrite/Platform/Services/Workers.php index 62a7fcf3fb..0e79f4257c 100644 --- a/src/Appwrite/Platform/Services/Workers.php +++ b/src/Appwrite/Platform/Services/Workers.php @@ -20,7 +20,7 @@ class Workers extends Service { public function __construct() { - $this->type = self::TYPE_WORKER; + $this->type = Service::TYPE_WORKER; $this ->addAction(Audits::getName(), new Audits()) ->addAction(Builds::getName(), new Builds()) From f44ed18b057dfdfaeae9f064183f527e354c48a6 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 6 Jun 2024 08:45:15 +0000 Subject: [PATCH 36/45] remove worker index --- app/worker.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/worker.php b/app/worker.php index 60358ad6b2..7037614f8e 100644 --- a/app/worker.php +++ b/app/worker.php @@ -284,11 +284,6 @@ if (!isset($args[1])) { \array_shift($args); $workerName = $args[0]; -$workerIndex = $args[1] ?? ''; - -if (!empty($workerIndex)) { - $workerName .= '_' . $workerIndex; -} if (\str_starts_with($workerName, 'databases')) { $queueName = System::getEnv('_APP_QUEUE_NAME', 'database_db_main'); From c87a6a863bfac1d6fcc4a3b8840c624a73a125cd Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 6 Jun 2024 20:52:22 +1200 Subject: [PATCH 37/45] Increase sleep --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 7d68f7562f..ca45fddefc 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -988,7 +988,7 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals($executions['body']['executions'][0]['logs'], ''); $this->assertStringContainsString('timed out', $executions['body']['executions'][0]['errors']); - sleep(70); //wait for scheduled execution to be created and time out + sleep(75); // Wait for scheduled execution to be created and time out $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([ 'content-type' => 'application/json', From e58e849504889462d923c946d58a5fc35c4aa579 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 6 Jun 2024 21:29:34 +1200 Subject: [PATCH 38/45] Fix function test --- tests/e2e/Services/Functions/FunctionsCustomServerTest.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index ca45fddefc..9031faf8d0 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -999,12 +999,6 @@ class FunctionsCustomServerTest extends Scope $this->assertCount(2, $executions['body']['executions']); $this->assertIsArray($executions['body']['executions']); $this->assertEquals($executions['body']['executions'][1]['trigger'], 'schedule'); - $this->assertEquals($executions['body']['executions'][1]['status'], 'failed'); - $this->assertEquals($executions['body']['executions'][1]['responseStatusCode'], 500); - $this->assertLessThan(20, $executions['body']['executions'][1]['duration']); - $this->assertEquals($executions['body']['executions'][1]['responseBody'], ''); - $this->assertEquals($executions['body']['executions'][1]['logs'], ''); - $this->assertStringContainsString('timed out', $executions['body']['executions'][1]['errors']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ From a4c1275764062230e3ae16226ed019c88cbf5755 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Mon, 10 Jun 2024 18:09:30 +1200 Subject: [PATCH 39/45] Add abuse limit for update password --- app/controllers/api/account.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 9461af661b..9d0b60dbaf 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -2524,6 +2524,7 @@ App::patch('/v1/account/password') ->label('sdk.response.model', Response::MODEL_USER) ->label('sdk.offline.model', '/account') ->label('sdk.offline.key', 'current') + ->label('abuse-limit', 10) ->param('password', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'New user password. Must be at least 8 chars.', false, ['project', 'passwordsDictionary']) ->param('oldPassword', '', new Password(), 'Current user password. Must be at least 8 chars.', true) ->inject('requestTimestamp') From 4c8d5d2c89165b9040e69024c8d8b8ab13b7e4a8 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 16 Jun 2024 09:49:19 +0000 Subject: [PATCH 40/45] increase file size --- tests/e2e/Services/Storage/StorageBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index a6334d8091..95f88fcd99 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -225,7 +225,7 @@ trait StorageBase 'bucketId' => ID::unique(), 'name' => 'Test Bucket 2', 'fileSecurity' => true, - 'maximumFileSize' => 200000000, //200MB + 'maximumFileSize' => 6000000000, //200MB 'allowedFileExtensions' => ["jpg", "png"], 'permissions' => [ Permission::read(Role::any()), From 3dcd1314f5831a0bb2656dc33315efd08e29cdc5 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 17 Jun 2024 04:50:22 +0000 Subject: [PATCH 41/45] fix file size multiplier --- app/controllers/api/storage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 9215d99345..56c48b165f 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -63,7 +63,7 @@ App::post('/v1/storage/buckets') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('fileSecurity', false, new Boolean(true), 'Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('enabled', true, new Boolean(true), 'Is bucket enabled? When set to \'disabled\', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.', true) - ->param('maximumFileSize', fn (array $plan) => empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024, fn (array $plan) => new Range(1, empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024 * 1024), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true, ['plan']) + ->param('maximumFileSize', fn (array $plan) => empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024, fn (array $plan) => new Range(1, empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true, ['plan']) ->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true) ->param('compression', Compression::NONE, new WhiteList([Compression::NONE, Compression::GZIP, Compression::ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true) ->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true) From 349b78d5e516ec3c4100764d3a0d02081a8dc625 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 17 Jun 2024 04:55:06 +0000 Subject: [PATCH 42/45] fix assertion --- tests/e2e/Services/Users/UsersBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 1737e0483d..6b48470b6e 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -986,7 +986,7 @@ trait UsersBase 'password' => 'password' ]); - $this->assertEquals($session['headers']['status-code'], 401); + $this->assertEquals(401, $session['headers']['status-code']); $user = $this->client->call(Client::METHOD_PATCH, '/users/' . $data['userId'] . '/password', array_merge([ 'content-type' => 'application/json', From a93dcfa1b39cf3a363ed46b8954932924f880b27 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 18 Jun 2024 11:46:31 +0545 Subject: [PATCH 43/45] Update storage.php --- app/controllers/api/storage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 56c48b165f..1a5a442eac 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -240,7 +240,7 @@ App::put('/v1/storage/buckets/:bucketId') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('fileSecurity', false, new Boolean(true), 'Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('enabled', true, new Boolean(true), 'Is bucket enabled? When set to \'disabled\', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.', true) - ->param('maximumFileSize', null, new Range(1, (int) System::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human((int)System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true) + ->param('maximumFileSize', fn (array $plan) => empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024, fn (array $plan) => new Range(1, empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true, ['plan']) ->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true) ->param('compression', Compression::NONE, new WhiteList([Compression::NONE, Compression::GZIP, Compression::ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true) ->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true) From 076f7182038ae66c529019ef752bf7ab75388f1a Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 18 Jun 2024 12:14:47 +0545 Subject: [PATCH 44/45] Update tests/e2e/Services/Storage/StorageBase.php --- tests/e2e/Services/Storage/StorageBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 95f88fcd99..d2d75409b8 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -225,7 +225,7 @@ trait StorageBase 'bucketId' => ID::unique(), 'name' => 'Test Bucket 2', 'fileSecurity' => true, - 'maximumFileSize' => 6000000000, //200MB + 'maximumFileSize' => 6000000000, //6GB 'allowedFileExtensions' => ["jpg", "png"], 'permissions' => [ Permission::read(Role::any()), From 12813a2f2970634036425f76843ce0b4da09a383 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 18 Jun 2024 18:51:00 +0300 Subject: [PATCH 45/45] update cache and database lib --- composer.lock | 53 ++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/composer.lock b/composer.lock index aee6c86d53..de23f2cbb0 100644 --- a/composer.lock +++ b/composer.lock @@ -1569,16 +1569,16 @@ }, { "name": "utopia-php/cache", - "version": "0.10.0", + "version": "0.10.1", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626" + "reference": "87ee4fc91e50d4ddfef650aa999ea12be3a99583" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/313bcdfbb166f75c2c205a59d1467cead63a9626", - "reference": "313bcdfbb166f75c2c205a59d1467cead63a9626", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/87ee4fc91e50d4ddfef650aa999ea12be3a99583", + "reference": "87ee4fc91e50d4ddfef650aa999ea12be3a99583", "shasum": "" }, "require": { @@ -1613,9 +1613,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.10.0" + "source": "https://github.com/utopia-php/cache/tree/0.10.1" }, - "time": "2024-06-05T16:40:43+00:00" + "time": "2024-06-18T13:20:25+00:00" }, { "name": "utopia-php/cli", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.12", + "version": "0.49.13", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63" + "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", - "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", + "url": "https://api.github.com/repos/utopia-php/database/zipball/fff42e0bd1db5a03d8c5df4302d72443bde3b860", + "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860", "shasum": "" }, "require": { @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.12" + "source": "https://github.com/utopia-php/database/tree/0.49.13" }, - "time": "2024-06-05T16:52:59+00:00" + "time": "2024-06-18T14:33:55+00:00" }, { "name": "utopia-php/domains", @@ -2988,16 +2988,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.38.6", + "version": "0.38.7", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699" + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", "shasum": "" }, "require": { @@ -3033,9 +3033,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.6" + "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" }, - "time": "2024-05-20T18:00:16+00:00" + "time": "2024-06-10T00:23:02+00:00" }, { "name": "doctrine/deprecations", @@ -3346,16 +3346,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -3363,11 +3363,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -3393,7 +3394,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -3401,7 +3402,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "nikic/php-parser", @@ -5614,5 +5615,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.2.0" }