From 6d357d617dd6dd6a93fc22ec55ea240f733c4c46 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Mon, 11 Dec 2023 23:37:32 +0000 Subject: [PATCH 01/18] Add a flag to install and upgrade commands to not start Appwrite This can be useful for cases where the developer only wants the files to be generated and doesn't want to start Appwrite. --- src/Appwrite/Platform/Tasks/Install.php | 14 +++++++++----- src/Appwrite/Platform/Tasks/Upgrade.php | 8 +++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Install.php b/src/Appwrite/Platform/Tasks/Install.php index eb419ade11..8591f4bcc3 100644 --- a/src/Appwrite/Platform/Tasks/Install.php +++ b/src/Appwrite/Platform/Tasks/Install.php @@ -8,6 +8,7 @@ use Appwrite\Docker\Env; use Appwrite\Utopia\View; use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\Validator\Boolean; use Utopia\Validator\Text; use Utopia\Platform\Action; @@ -29,10 +30,11 @@ class Install extends Action ->param('organization', 'appwrite', new Text(0), 'Docker Registry organization', true) ->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true) ->param('interactive', 'Y', new Text(1), 'Run an interactive session', true) - ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive)); + ->param('noStart', false, new Boolean(true), 'Run an interactive session', true) + ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive, $noStart) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart)); } - public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive): void + public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive, bool $noStart): void { $config = Config::getParam('variables'); $defaultHTTPPort = '80'; @@ -220,9 +222,11 @@ class Install extends Action } } - Console::log("Running \"docker compose up -d --remove-orphans --renew-anon-volumes\""); - - $exit = Console::execute("$env docker compose --project-directory $this->path up -d --remove-orphans --renew-anon-volumes", '', $stdout, $stderr); + $exit = 0; + if (!$noStart) { + Console::log("Running \"docker compose up -d --remove-orphans --renew-anon-volumes\""); + $exit = Console::execute("$env docker compose --project-directory $this->path up -d --remove-orphans --renew-anon-volumes", '', $stdout, $stderr); + } if ($exit !== 0) { $message = 'Failed to install Appwrite dockers'; diff --git a/src/Appwrite/Platform/Tasks/Upgrade.php b/src/Appwrite/Platform/Tasks/Upgrade.php index e3f0458394..1f3e148a82 100644 --- a/src/Appwrite/Platform/Tasks/Upgrade.php +++ b/src/Appwrite/Platform/Tasks/Upgrade.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Tasks; use Utopia\CLI\Console; +use Utopia\Validator\Boolean; use Utopia\Validator\Text; class Upgrade extends Install @@ -21,10 +22,11 @@ class Upgrade extends Install ->param('organization', 'appwrite', new Text(0), 'Docker Registry organization', true) ->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true) ->param('interactive', 'Y', new Text(1), 'Run an interactive session', true) - ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive)); + ->param('noStart', false, new Boolean(true), 'Run an interactive session', true) + ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive, $noStart) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart)); } - public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive): void + public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive, bool $noStart): void { // Check for previous installation $data = @file_get_contents($this->path . '/docker-compose.yml'); @@ -37,6 +39,6 @@ class Upgrade extends Install Console::log(' └── docker-compose.yml'); Console::exit(1); } - parent::action($httpPort, $httpsPort, $organization, $image, $interactive); + parent::action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart); } } From e56b30e6a6c9d7d5416383e7329ccc4738a645eb Mon Sep 17 00:00:00 2001 From: Serhat Aksakal <49079271+fanksin@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:10:44 +0300 Subject: [PATCH 02/18] Update tr.json --- app/config/locale/translations/tr.json | 56 ++++++++++++++------------ 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/app/config/locale/translations/tr.json b/app/config/locale/translations/tr.json index 6a94aeacae..e82317de01 100644 --- a/app/config/locale/translations/tr.json +++ b/app/config/locale/translations/tr.json @@ -3,30 +3,36 @@ "settings.locale": "tr", "settings.direction": "ltr", "emails.sender": "%s Takımı", - "emails.verification.subject": "", - "emails.verification.hello": "", - "emails.verification.body": "", - "emails.verification.footer": "", - "emails.verification.thanks": "", - "emails.verification.signature": "", - "emails.magicSession.subject": "", - "emails.magicSession.hello": "", - "emails.magicSession.body": "", - "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", - "emails.magicSession.signature": "", - "emails.recovery.subject": "", - "emails.recovery.hello": "", - "emails.recovery.body": "", - "emails.recovery.footer": "", - "emails.recovery.thanks": "", - "emails.recovery.signature": "", - "emails.invitation.subject": "", - "emails.invitation.hello": "", - "emails.invitation.body": "", - "emails.invitation.footer": "", - "emails.invitation.thanks": "", - "emails.invitation.signature": "", + "emails.verification.subject": "Hesabını Doğrula", + "emails.verification.hello": "Merhaba {{user}}", + "emails.verification.body": "Eposta adresini doğrulamak için bu bağlantıyı kullanın.", + "emails.verification.footer": "Eğer bu eposta adresini doğrulamak isteyen siz değilseniz devam etmeyin.", + "emails.verification.thanks": "Teşekkürler", + "emails.verification.signature": "{{project}} takımı", + "emails.magicSession.subject": "Giriş", + "emails.magicSession.hello": "Merhaba,", + "emails.magicSession.body": "Giriş yapmak için tıklayın.", + "emails.magicSession.footer": "Eğer bu eposta adresini kullanarak giriş yapmak istemediyseniz devam etmeyin.", + "emails.magicSession.thanks": "Teşekkürler", + "emails.magicSession.signature": "{{project}} takımı", + "emails.recovery.subject": "Şifremi Sıfırla", + "emails.recovery.hello": "Merhaba {{user}}", + "emails.recovery.body": "{{project}} şifrenizi sıfırlamak için bu bağlantıyı kullanın.", + "emails.recovery.footer": "Eğer şifre sıfırlama talebinde bulunmadıysanız devam etmeyin.", + "emails.recovery.thanks": "Teşekkürler", + "emails.recovery.signature": "{{project}} takımı", + "emails.invitation.subject": "%s üzerinde %s Takımına Davet", + "emails.invitation.hello": "Merhaba", + "emails.invitation.body": "Bu epostayı aldınız, çünkü {{owner}} sizi {{project}} üzerinde {{team}} takımının üyesi olmaya davet etti.", + "emails.invitation.footer": "Eğer ilgilenmiyorsanız devam etmeyin.", + "emails.invitation.thanks": "Teşekkürler", + "emails.invitation.signature": "{{project}} takımı", + "emails.certificate.subject": "%s için sertifika hatası", + "emails.certificate.hello": "Merhaba", + "emails.certificate.body": "Alan adınız '{{domain}}' için sertifika oluşturulamadı. Deneme sayısı {{attempt}} ve hata sebebi: {{error}}", + "emails.certificate.footer": "Geçmiş sertifikanız ilk denemeden sonra 30 gün daha geçerli kalacaktır. Bu konuyu araştırmanızı öneriyoruz, aksi taktirde alan adınız SSL sertifikasız kalacaktır.", + "emails.certificate.thanks": "Teşekkürler", + "emails.certificate.signature": "{{project}} takımı", "locale.country.unknown": "Bilinmeyen", "countries.af": "Afganistan", "countries.ao": "Angola", @@ -229,4 +235,4 @@ "continents.na": "Kuzey Amerika", "continents.oc": "Okyanusya", "continents.sa": "Güney Amerika" -} \ No newline at end of file +} From 26ac88c32e3548c6b14add906e75ed512f4a8662 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 05:54:59 +0000 Subject: [PATCH 03/18] validate create permission while updating chunk uploaded file --- app/controllers/api/storage.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 1fae48dae0..d390f9ef1c 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -621,8 +621,13 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('openSSLIV', $openSSLIV) ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); - - $file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file); + + // Validate create permission + $validator = new Authorization(Database::PERMISSION_CREATE); + if (!$validator->isValid($bucket->getCreate())) { + throw new Exception(Exception::USER_UNAUTHORIZED); + } + $file = Authorization::skip(fn() => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -659,7 +664,12 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('chunksUploaded', $chunksUploaded) ->setAttribute('metadata', $metadata); - $file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file); + // Validate create permission + $validator = new Authorization(Database::PERMISSION_CREATE); + if (!$validator->isValid($bucket->getCreate())) { + throw new Exception(Exception::USER_UNAUTHORIZED); + } + $file = Authorization::skip(fn() => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); From b6b1b396b384c4d4b6cc520586c0468753a7d14e Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 06:00:43 +0000 Subject: [PATCH 04/18] update chunk upload test --- tests/e2e/Services/Storage/StorageBase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 5463740761..be01d95368 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -74,10 +74,7 @@ trait StorageBase 'name' => 'Test Bucket 2', 'fileSecurity' => true, 'permissions' => [ - Permission::read(Role::any()), Permission::create(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), ], ]); $this->assertEquals(201, $bucket2['headers']['status-code']); From a6b4ade39b72bb595bd5c7c03063bf6d475437d8 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 06:06:18 +0000 Subject: [PATCH 05/18] update large file upload test to not include update permission --- tests/e2e/Services/Storage/StorageBase.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index be01d95368..eb6a52db6b 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -107,9 +107,7 @@ trait StorageBase 'fileId' => $fileId, 'file' => $curlFile, 'permissions' => [ - Permission::read(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), + Permission::read(Role::any()) ], ]); $counter++; From cbd3e85b389400740973a9e8948b457062adcb9e Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 06:07:28 +0000 Subject: [PATCH 06/18] fix formatting --- 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 d390f9ef1c..687971c2d0 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -621,7 +621,7 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('openSSLIV', $openSSLIV) ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); - + // Validate create permission $validator = new Authorization(Database::PERMISSION_CREATE); if (!$validator->isValid($bucket->getCreate())) { From f1ba7b08ab40718aa08f0eb0b682676ca0a74ec7 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Wed, 27 Dec 2023 23:35:32 +0000 Subject: [PATCH 07/18] Update the delete identity endpoints to set the params and payload Because no payload was set, the event params (userId and identityId) wasn't picked up automatically. This updates the endpoints so that the payload is set, but also makes sure to set the userId and identityId params since the identityId param's key doesn't match the key in the payload. --- app/controllers/api/account.php | 10 ++++++++-- app/controllers/api/users.php | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index c210b19f4f..9cbe6ce7ef 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -842,7 +842,7 @@ App::get('/v1/account/identities') }); App::delete('/v1/account/identities/:identityId') - ->desc('Delete Identity') + ->desc('Delete identity') ->groups(['api', 'account']) ->label('scope', 'account') ->label('event', 'users.[userId].identities.[identityId].delete') @@ -859,7 +859,8 @@ App::delete('/v1/account/identities/:identityId') ->param('identityId', '', new UID(), 'Identity ID.') ->inject('response') ->inject('dbForProject') - ->action(function (string $identityId, Response $response, Database $dbForProject) { + ->inject('queueForEvents') + ->action(function (string $identityId, Response $response, Database $dbForProject, Event $queueForEvents) { $identity = $dbForProject->getDocument('identities', $identityId); @@ -869,6 +870,11 @@ App::delete('/v1/account/identities/:identityId') $dbForProject->deleteDocument('identities', $identityId); + $queueForEvents + ->setParam('userId', $identity->getAttribute('userId')) + ->setParam('identityId', $identity->getId()) + ->setPayload($response->output($identity, Response::MODEL_IDENTITY)); + return $response->noContent(); }); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 0869453cc9..30f52c614e 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -1211,7 +1211,7 @@ App::delete('/v1/users/:userId') }); App::delete('/v1/users/identities/:identityId') - ->desc('Delete Identity') + ->desc('Delete identity') ->groups(['api', 'users']) ->label('event', 'users.[userId].identities.[identityId].delete') ->label('scope', 'users.write') @@ -1227,7 +1227,8 @@ App::delete('/v1/users/identities/:identityId') ->param('identityId', '', new UID(), 'Identity ID.') ->inject('response') ->inject('dbForProject') - ->action(function (string $identityId, Response $response, Database $dbForProject) { + ->inject('queueForEvents') + ->action(function (string $identityId, Response $response, Database $dbForProject, Event $queueForEvents) { $identity = $dbForProject->getDocument('identities', $identityId); @@ -1237,6 +1238,11 @@ App::delete('/v1/users/identities/:identityId') $dbForProject->deleteDocument('identities', $identityId); + $queueForEvents + ->setParam('userId', $identity->getAttribute('userId')) + ->setParam('identityId', $identity->getId()) + ->setPayload($response->output($identity, Response::MODEL_IDENTITY)); + return $response->noContent(); }); From 5455db7c7fac85b8a567558f3211d56776b580c8 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 11:26:45 +0000 Subject: [PATCH 08/18] improve order --- app/controllers/api/storage.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 5ef810fec7..533e5c73a6 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -872,14 +872,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') throw new Exception(Exception::USER_UNAUTHORIZED); } - if ((\strpos($request->getAccept(), 'image/webp') === false) && ('webp' === $output)) { // Fallback webp to jpeg when no browser support - $output = 'jpg'; - } - - $inputs = Config::getParam('storage-inputs'); - $outputs = Config::getParam('storage-outputs'); - $fileLogos = Config::getParam('storage-logos'); - if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { @@ -890,6 +882,14 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') throw new Exception(Exception::STORAGE_FILE_NOT_FOUND); } + if ((\strpos($request->getAccept(), 'image/webp') === false) && ('webp' === $output)) { // Fallback webp to jpeg when no browser support + $output = 'jpg'; + } + + $inputs = Config::getParam('storage-inputs'); + $outputs = Config::getParam('storage-outputs'); + $fileLogos = Config::getParam('storage-logos'); + $path = $file->getAttribute('path'); $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); $algorithm = $file->getAttribute('algorithm', 'none'); @@ -926,7 +926,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $output = empty($type) ? (array_search($mime, $outputs) ?? 'jpg') : $type; } - $source = $deviceFiles->read($path); if (!empty($cipher)) { // Decrypt From a28be2bf48f91291af3b5099d239e81052075d50 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 11:32:04 +0000 Subject: [PATCH 09/18] return when response is sent to prevent further execution --- app/controllers/api/storage.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 533e5c73a6..99aa16226b 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1258,10 +1258,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') $response->send(substr($source, $start, ($end - $start + 1))); } $response->send($source); + return; } if (!empty($rangeHeader)) { $response->send($deviceFiles->read($path, $start, ($end - $start + 1))); + return; } $size = $deviceFiles->getFileSize($path); From 9cb5eb0180f94bba220c65b7b60f1e4815db7723 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 11:42:40 +0000 Subject: [PATCH 10/18] use constants for compression type --- app/controllers/api/storage.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 99aa16226b..5a03edaf4a 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -892,7 +892,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $file->getAttribute('path'); $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); - $algorithm = $file->getAttribute('algorithm', 'none'); + $algorithm = $file->getAttribute('algorithm', COMPRESSION_TYPE_NONE); $cipher = $file->getAttribute('openSSLCipher'); $mime = $file->getAttribute('mimeType'); if (!\in_array($mime, $inputs) || $file->getAttribute('sizeActual') > (int) App::getEnv('_APP_STORAGE_PREVIEW_LIMIT', 20000000)) { @@ -903,7 +903,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $fileLogos['default_image']; } - $algorithm = 'none'; + $algorithm = COMPRESSION_TYPE_NONE; $cipher = null; $background = (empty($background)) ? 'eceff1' : $background; $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); @@ -940,11 +940,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') } switch ($algorithm) { - case 'zstd': + case COMPRESSION_TYPE_ZSTD: $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case 'gzip': + case COMPRESSION_TYPE_GZIP: $compressor = new GZIP(); $source = $compressor->decompress($source); break; @@ -1085,15 +1085,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') ); } - switch ($file->getAttribute('algorithm', 'none')) { - case 'zstd': + switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { + case COMPRESSION_TYPE_ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case 'gzip': + case COMPRESSION_TYPE_GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } @@ -1236,15 +1236,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') ); } - switch ($file->getAttribute('algorithm', 'none')) { - case 'zstd': + switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { + case COMPRESSION_TYPE_ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case 'gzip': + case COMPRESSION_TYPE_GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } From 1c236959ba776e2877b42fb3ddfa8f3ac118a1f2 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 29 Dec 2023 01:49:56 +0000 Subject: [PATCH 11/18] fix algorithm attribute on file if size is above read buffer size --- app/controllers/api/storage.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 5a03edaf4a..aaa1df9d32 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -551,6 +551,11 @@ App::post('/v1/storage/buckets/:bucketId/files') break; } $data = $compressor->compress($data); + } else { + // reset the algorithm to none as we do not compress the file + // if file size exceedes the APP_STORAGE_READ_BUFFER + // regardless the bucket compression algoorithm + $algorithm = COMPRESSION_TYPE_NONE; } if ($bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER) { From c99976560d13a56401b808650e38d6d817005cf7 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 31 Dec 2023 11:37:22 +0000 Subject: [PATCH 12/18] update utopia-storage --- composer.lock | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/composer.lock b/composer.lock index 3518396665..17f0325ded 100644 --- a/composer.lock +++ b/composer.lock @@ -1906,16 +1906,16 @@ }, { "name": "utopia-php/database", - "version": "0.45.2", + "version": "0.45.3", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "dc789f2c1fd8b5ee07ff883e11c9ad7970824788" + "reference": "33b4e9a4a6c29f6bb7e108e134b283d585955789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/dc789f2c1fd8b5ee07ff883e11c9ad7970824788", - "reference": "dc789f2c1fd8b5ee07ff883e11c9ad7970824788", + "url": "https://api.github.com/repos/utopia-php/database/zipball/33b4e9a4a6c29f6bb7e108e134b283d585955789", + "reference": "33b4e9a4a6c29f6bb7e108e134b283d585955789", "shasum": "" }, "require": { @@ -1956,9 +1956,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.45.2" + "source": "https://github.com/utopia-php/database/tree/0.45.3" }, - "time": "2023-11-15T03:38:47+00:00" + "time": "2023-12-28T11:12:26+00:00" }, { "name": "utopia-php/domains", @@ -2476,16 +2476,16 @@ }, { "name": "utopia-php/platform", - "version": "0.5.0", + "version": "0.5.1", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "229a7b1fa1f39afd1532f7a515326a6afc222a26" + "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/229a7b1fa1f39afd1532f7a515326a6afc222a26", - "reference": "229a7b1fa1f39afd1532f7a515326a6afc222a26", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/3eceef0b6593fe0f7d2efd36d40402a395a4c285", + "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285", "shasum": "" }, "require": { @@ -2493,7 +2493,7 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.31.*" + "utopia-php/framework": "0.*.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2519,9 +2519,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.0" + "source": "https://github.com/utopia-php/platform/tree/0.5.1" }, - "time": "2023-10-16T20:28:49+00:00" + "time": "2023-12-26T16:14:41+00:00" }, { "name": "utopia-php/pools", @@ -2742,16 +2742,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.1", + "version": "0.18.2", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824" + "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/983e6dee137012f9f57f126d3c79aab54e4e8824", - "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/130e7c4f305c2e1d5aa86226aaee25c9d5a41073", + "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073", "shasum": "" }, "require": { @@ -2791,9 +2791,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.1" + "source": "https://github.com/utopia-php/storage/tree/0.18.2" }, - "time": "2023-10-24T14:44:19+00:00" + "time": "2023-12-31T11:33:28+00:00" }, { "name": "utopia-php/swoole", @@ -2904,23 +2904,23 @@ }, { "name": "utopia-php/vcs", - "version": "0.6.2", + "version": "0.6.4", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "f135291b87cb45335fc6608722e7f89894bc33ee" + "reference": "b2595a50a4897a8c88319240810055b7a96efd6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/f135291b87cb45335fc6608722e7f89894bc33ee", - "reference": "f135291b87cb45335fc6608722e7f89894bc33ee", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/b2595a50a4897a8c88319240810055b7a96efd6d", + "reference": "b2595a50a4897a8c88319240810055b7a96efd6d", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", "utopia-php/cache": "^0.8.0", - "utopia-php/framework": "0.31.*" + "utopia-php/framework": "0.*.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2947,9 +2947,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.6.2" + "source": "https://github.com/utopia-php/vcs/tree/0.6.4" }, - "time": "2023-11-08T15:36:03+00:00" + "time": "2023-12-26T15:38:19+00:00" }, { "name": "utopia-php/websocket", @@ -3487,16 +3487,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -3537,9 +3537,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2023-12-10T21:03:43+00:00" }, { "name": "phar-io/manifest", @@ -3891,16 +3891,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.4", + "version": "1.24.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fedf211ff14ec8381c9bf5714e33a7a552dd1acc", + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc", "shasum": "" }, "require": { @@ -3932,29 +3932,29 @@ "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.24.4" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.5" }, - "time": "2023-11-26T18:29:22+00:00" + "time": "2023-12-16T09:33:33+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4004,7 +4004,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" }, "funding": [ { @@ -4012,7 +4012,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4651,20 +4651,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -4696,7 +4696,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -4704,7 +4704,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -4978,20 +4978,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -5023,7 +5023,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -5031,7 +5031,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", From d070989f73c50b3515d1e5317673c22e69c7c570 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 31 Dec 2023 11:46:27 +0000 Subject: [PATCH 13/18] update utopia storage --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 17f0325ded..acd65d61a1 100644 --- a/composer.lock +++ b/composer.lock @@ -2742,16 +2742,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.2", + "version": "0.18.3", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073" + "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/130e7c4f305c2e1d5aa86226aaee25c9d5a41073", - "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/faa0279519ac14f3501e8b138e0865ad9d12bff6", + "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6", "shasum": "" }, "require": { @@ -2791,9 +2791,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.2" + "source": "https://github.com/utopia-php/storage/tree/0.18.3" }, - "time": "2023-12-31T11:33:28+00:00" + "time": "2023-12-31T11:45:12+00:00" }, { "name": "utopia-php/swoole", From a2ad8700845b1b1b9c3e0fa4d0949798054a98a4 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 31 Dec 2023 11:46:45 +0000 Subject: [PATCH 14/18] use compression constant from utopia/storage --- app/controllers/api/storage.php | 35 ++++++++++--------- app/init.php | 4 --- src/Appwrite/Utopia/Response/Model/Bucket.php | 3 +- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index aaa1df9d32..91efb21f3e 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -44,6 +44,7 @@ use Utopia\Validator\Text; use Utopia\Validator\WhiteList; use Utopia\DSN\DSN; use Utopia\Swoole\Request; +use Utopia\Storage\Compression\Compression; App::post('/v1/storage/buckets') ->desc('Create bucket') @@ -67,7 +68,7 @@ App::post('/v1/storage/buckets') ->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', (int) App::getEnv('_APP_STORAGE_LIMIT', 0), new Range(1, (int) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true) ->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_TYPE_NONE, new WhiteList([COMPRESSION_TYPE_NONE, COMPRESSION_TYPE_GZIP, COMPRESSION_TYPE_ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_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('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) ->param('antivirus', true, new Boolean(true), 'Is virus scanning enabled? For file size above ' . Storage::human(APP_LIMIT_ANTIVIRUS, 0) . ' AntiVirus scanning is skipped even if it\'s enabled', true) ->inject('response') @@ -241,7 +242,7 @@ App::put('/v1/storage/buckets/:bucketId') ->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) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human((int)App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true) ->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_TYPE_NONE, new WhiteList([COMPRESSION_TYPE_NONE, COMPRESSION_TYPE_GZIP, COMPRESSION_TYPE_ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_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('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) ->param('antivirus', true, new Boolean(true), 'Is virus scanning enabled? For file size above ' . Storage::human(APP_LIMIT_ANTIVIRUS, 0) . ' AntiVirus scanning is skipped even if it\'s enabled', true) ->inject('response') @@ -538,14 +539,14 @@ App::post('/v1/storage/buckets/:bucketId/files') $fileHash = $deviceFiles->getFileHash($path); // Get file hash before compression and encryption $data = ''; // Compression - $algorithm = $bucket->getAttribute('compression', COMPRESSION_TYPE_NONE); - if ($fileSize <= APP_STORAGE_READ_BUFFER && $algorithm != COMPRESSION_TYPE_NONE) { + $algorithm = $bucket->getAttribute('compression', Compression::NONE); + if ($fileSize <= APP_STORAGE_READ_BUFFER && $algorithm != Compression::NONE) { $data = $deviceFiles->read($path); switch ($algorithm) { - case COMPRESSION_TYPE_ZSTD: + case Compression::ZSTD: $compressor = new Zstd(); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: default: $compressor = new GZIP(); break; @@ -555,7 +556,7 @@ App::post('/v1/storage/buckets/:bucketId/files') // reset the algorithm to none as we do not compress the file // if file size exceedes the APP_STORAGE_READ_BUFFER // regardless the bucket compression algoorithm - $algorithm = COMPRESSION_TYPE_NONE; + $algorithm = Compression::NONE; } if ($bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER) { @@ -897,7 +898,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $file->getAttribute('path'); $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); - $algorithm = $file->getAttribute('algorithm', COMPRESSION_TYPE_NONE); + $algorithm = $file->getAttribute('algorithm', Compression::NONE); $cipher = $file->getAttribute('openSSLCipher'); $mime = $file->getAttribute('mimeType'); if (!\in_array($mime, $inputs) || $file->getAttribute('sizeActual') > (int) App::getEnv('_APP_STORAGE_PREVIEW_LIMIT', 20000000)) { @@ -908,7 +909,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $fileLogos['default_image']; } - $algorithm = COMPRESSION_TYPE_NONE; + $algorithm = Compression::NONE; $cipher = null; $background = (empty($background)) ? 'eceff1' : $background; $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); @@ -945,11 +946,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') } switch ($algorithm) { - case COMPRESSION_TYPE_ZSTD: + case Compression::ZSTD: $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: $compressor = new GZIP(); $source = $compressor->decompress($source); break; @@ -1090,15 +1091,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') ); } - switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { - case COMPRESSION_TYPE_ZSTD: + switch ($file->getAttribute('algorithm', Compression::NONE)) { + case Compression::ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } @@ -1241,15 +1242,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') ); } - switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { - case COMPRESSION_TYPE_ZSTD: + switch ($file->getAttribute('algorithm', Compression::NONE)) { + case Compression::ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } diff --git a/app/init.php b/app/init.php index 72bf75d41b..924122ac20 100644 --- a/app/init.php +++ b/app/init.php @@ -173,10 +173,6 @@ const DELETE_TYPE_SESSIONS = 'sessions'; const DELETE_TYPE_CACHE_BY_TIMESTAMP = 'cacheByTimeStamp'; const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource'; const DELETE_TYPE_SCHEDULES = 'schedules'; -// Compression type -const COMPRESSION_TYPE_NONE = 'none'; -const COMPRESSION_TYPE_GZIP = 'gzip'; -const COMPRESSION_TYPE_ZSTD = 'zstd'; // Mail Types const MAIL_TYPE_VERIFICATION = 'verification'; const MAIL_TYPE_MAGIC_SESSION = 'magicSession'; diff --git a/src/Appwrite/Utopia/Response/Model/Bucket.php b/src/Appwrite/Utopia/Response/Model/Bucket.php index 3c5715efc2..f5261c026e 100644 --- a/src/Appwrite/Utopia/Response/Model/Bucket.php +++ b/src/Appwrite/Utopia/Response/Model/Bucket.php @@ -4,6 +4,7 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; +use Utopia\Storage\Compression\Compression; class Bucket extends Model { @@ -68,7 +69,7 @@ class Bucket extends Model ]) ->addRule('compression', [ 'type' => self::TYPE_STRING, - 'description' => 'Compression algorithm choosen for compression. Will be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_ZSTD . '](https://en.wikipedia.org/wiki/Zstd).', + 'description' => 'Compression algorithm choosen for compression. Will be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd).', 'default' => '', 'example' => 'gzip', 'array' => false From 879320e23ec198cd9049856301fbfb5342b9af40 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 2 Jan 2024 11:53:48 +0545 Subject: [PATCH 15/18] update comment regarding validation --- app/controllers/api/storage.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index e668ec2552..011f83f4b4 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -628,7 +628,12 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); - // Validate create permission + /** + * Validate create permission and skip authorization in updateDocument + * Without this, the file creation will fail when user doesn't have update permission + * However as with chunk upload even if we are updating, we are essentially creating a file + * adding it's new chunk so we validate create permission instead of update + */ $validator = new Authorization(Database::PERMISSION_CREATE); if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -670,7 +675,12 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('chunksUploaded', $chunksUploaded) ->setAttribute('metadata', $metadata); - // Validate create permission + /** + * Validate create permission and skip authorization in updateDocument + * Without this, the file creation will fail when user doesn't have update permission + * However as with chunk upload even if we are updating, we are essentially creating a file + * adding it's new chunk so we validate create permission instead of update + */ $validator = new Authorization(Database::PERMISSION_CREATE); if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); From b6b5570b0b75f7e3c8a1fb6307bbadc589f1cc08 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Wed, 3 Jan 2024 19:48:31 +0000 Subject: [PATCH 16/18] Add General E2E tests to CI pipeline --- .github/workflows/tests.yml | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 842d61ff1c..2fb6840f6e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -75,8 +75,32 @@ jobs: - name: Run Unit Tests run: docker compose exec appwrite test /usr/src/code/tests/unit - e2e_test: - name: E2E Test + e2e_general_test: + name: E2E General Test + runs-on: ubuntu-latest + needs: setup + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: Load Cache + uses: actions/cache@v3 + with: + key: ${{ env.CACHE_KEY }} + path: /tmp/${{ env.IMAGE }}.tar + fail-on-cache-miss: true + + - name: Load and Start Appwrite + run: | + docker load --input /tmp/${{ env.IMAGE }}.tar + docker compose up -d + sleep 10 + + - name: Run General Tests + run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/General --debug + + e2e_service_test: + name: E2E Service Test runs-on: ubuntu-latest needs: setup strategy: @@ -119,4 +143,4 @@ jobs: sleep 10 - name: Run ${{matrix.service}} Tests - run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug \ No newline at end of file + run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug From fbd277f6aa0ff161838a60e79b950e5a3f58e3f6 Mon Sep 17 00:00:00 2001 From: Ben Humphries Date: Thu, 4 Jan 2024 05:46:08 -0500 Subject: [PATCH 17/18] executor: pass build timeout to runtimes (#7350) open-runtimes executor (v1/runtimes) supports passing a timeout parameter that defaults to 600 seconds. ->param('timeout', 600, new Integer(), 'Commands execution time in seconds.', true) https://github.com/open-runtimes/executor/blob/main/app/http.php#L383 This change passes the _APP_FUNCTIONS_BUILD_TIMEOUT env var. --- src/Executor/Executor.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index c7388069a1..8e73747047 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -72,6 +72,7 @@ class Executor ) { $runtimeId = "$projectId-$deploymentId-build"; $route = "/runtimes"; + $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); $params = [ 'runtimeId' => $runtimeId, 'source' => $source, @@ -84,10 +85,9 @@ class Executor 'cpus' => $this->cpus, 'memory' => $this->memory, 'version' => $version, + 'timeout' => $timeout, ]; - $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); - $response = $this->call(self::METHOD_POST, $route, [ 'x-opr-runtime-id' => $runtimeId ], $params, true, $timeout); $status = $response['headers']['status-code']; @@ -111,7 +111,7 @@ class Executor string $projectId, callable $callback ) { - $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); + $timeout = (int) App::getEnv('_APP_FUNCTIONS_BUILD_TIMEOUT', 900); $runtimeId = "$projectId-$deploymentId-build"; $route = "/runtimes/{$runtimeId}/logs"; From 864703fb4ee5711af4a05d6927111a9a70b38210 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Mon, 8 Jan 2024 20:56:51 +0000 Subject: [PATCH 18/18] Update the install/upgrade arguments to be kebab instead of camel case Kebab case like --http-port is much more common in CLIs than --httpPort. --- src/Appwrite/Platform/Tasks/Install.php | 6 +++--- src/Appwrite/Platform/Tasks/Upgrade.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Install.php b/src/Appwrite/Platform/Tasks/Install.php index 8591f4bcc3..c6107c6ba8 100644 --- a/src/Appwrite/Platform/Tasks/Install.php +++ b/src/Appwrite/Platform/Tasks/Install.php @@ -25,12 +25,12 @@ class Install extends Action { $this ->desc('Install Appwrite') - ->param('httpPort', '', new Text(4), 'Server HTTP port', true) - ->param('httpsPort', '', new Text(4), 'Server HTTPS port', true) + ->param('http-port', '', new Text(4), 'Server HTTP port', true) + ->param('https-port', '', new Text(4), 'Server HTTPS port', true) ->param('organization', 'appwrite', new Text(0), 'Docker Registry organization', true) ->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true) ->param('interactive', 'Y', new Text(1), 'Run an interactive session', true) - ->param('noStart', false, new Boolean(true), 'Run an interactive session', true) + ->param('no-start', false, new Boolean(true), 'Run an interactive session', true) ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive, $noStart) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart)); } diff --git a/src/Appwrite/Platform/Tasks/Upgrade.php b/src/Appwrite/Platform/Tasks/Upgrade.php index 1f3e148a82..341ce42fc4 100644 --- a/src/Appwrite/Platform/Tasks/Upgrade.php +++ b/src/Appwrite/Platform/Tasks/Upgrade.php @@ -17,12 +17,12 @@ class Upgrade extends Install { $this ->desc('Upgrade Appwrite') - ->param('httpPort', '', new Text(4), 'Server HTTP port', true) - ->param('httpsPort', '', new Text(4), 'Server HTTPS port', true) + ->param('http-port', '', new Text(4), 'Server HTTP port', true) + ->param('https-port', '', new Text(4), 'Server HTTPS port', true) ->param('organization', 'appwrite', new Text(0), 'Docker Registry organization', true) ->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true) ->param('interactive', 'Y', new Text(1), 'Run an interactive session', true) - ->param('noStart', false, new Boolean(true), 'Run an interactive session', true) + ->param('no-start', false, new Boolean(true), 'Run an interactive session', true) ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive, $noStart) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart)); }