diff --git a/.env b/.env index 65fb54cb04..0ccd1d02f2 100644 --- a/.env +++ b/.env @@ -23,27 +23,7 @@ _APP_DB_SCHEMA=appwrite _APP_DB_USER=user _APP_DB_PASS=password _APP_DB_ROOT_PASS=rootsecretpassword -_APP_STORAGE_DEVICE=Local -_APP_STORAGE_S3_ACCESS_KEY= -_APP_STORAGE_S3_SECRET= -_APP_STORAGE_S3_REGION=us-east-1 -_APP_STORAGE_S3_BUCKET= -_APP_STORAGE_DO_SPACES_ACCESS_KEY= -_APP_STORAGE_DO_SPACES_SECRET= -_APP_STORAGE_DO_SPACES_REGION=us-east-1 -_APP_STORAGE_DO_SPACES_BUCKET= -_APP_STORAGE_BACKBLAZE_ACCESS_KEY= -_APP_STORAGE_BACKBLAZE_SECRET= -_APP_STORAGE_BACKBLAZE_REGION=us-west-004 -_APP_STORAGE_BACKBLAZE_BUCKET= -_APP_STORAGE_LINODE_ACCESS_KEY= -_APP_STORAGE_LINODE_SECRET= -_APP_STORAGE_LINODE_REGION=eu-central-1 -_APP_STORAGE_LINODE_BUCKET= -_APP_STORAGE_WASABI_ACCESS_KEY= -_APP_STORAGE_WASABI_SECRET= -_APP_STORAGE_WASABI_REGION=eu-central-1 -_APP_STORAGE_WASABI_BUCKET= +_APP_STORAGE_CONNECTION= _APP_STORAGE_ANTIVIRUS=disabled _APP_STORAGE_ANTIVIRUS_HOST=clamav _APP_STORAGE_ANTIVIRUS_PORT=3310 diff --git a/Dockerfile b/Dockerfile index a7cae38502..66a39584b2 100755 --- a/Dockerfile +++ b/Dockerfile @@ -195,27 +195,7 @@ ENV _APP_SERVER=swoole \ _APP_STORAGE_ANTIVIRUS=enabled \ _APP_STORAGE_ANTIVIRUS_HOST=clamav \ _APP_STORAGE_ANTIVIRUS_PORT=3310 \ - _APP_STORAGE_DEVICE=Local \ - _APP_STORAGE_S3_ACCESS_KEY= \ - _APP_STORAGE_S3_SECRET= \ - _APP_STORAGE_S3_REGION= \ - _APP_STORAGE_S3_BUCKET= \ - _APP_STORAGE_DO_SPACES_ACCESS_KEY= \ - _APP_STORAGE_DO_SPACES_SECRET= \ - _APP_STORAGE_DO_SPACES_REGION= \ - _APP_STORAGE_DO_SPACES_BUCKET= \ - _APP_STORAGE_BACKBLAZE_ACCESS_KEY= \ - _APP_STORAGE_BACKBLAZE_SECRET= \ - _APP_STORAGE_BACKBLAZE_REGION= \ - _APP_STORAGE_BACKBLAZE_BUCKET= \ - _APP_STORAGE_LINODE_ACCESS_KEY= \ - _APP_STORAGE_LINODE_SECRET= \ - _APP_STORAGE_LINODE_REGION= \ - _APP_STORAGE_LINODE_BUCKET= \ - _APP_STORAGE_WASABI_ACCESS_KEY= \ - _APP_STORAGE_WASABI_SECRET= \ - _APP_STORAGE_WASABI_REGION= \ - _APP_STORAGE_WASABI_BUCKET= \ + _APP_STORAGE_CONNECTION= \ _APP_REDIS_HOST=redis \ _APP_REDIS_PORT=6379 \ _APP_DB_HOST=mariadb \ diff --git a/app/config/variables.php b/app/config/variables.php index 9f3bc018e8..942de3bd13 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -481,16 +481,24 @@ return [ 'filter' => '' ], [ - 'name' => '_APP_STORAGE_DEVICE', + 'name' => '_APP_STORAGE_DEVICE', // TODO : Should we keep it or deprecate it considering we can get the device from the scheme of the DSN 'description' => 'Select default storage device. The default value is \'Local\'. List of supported adapters are \'Local\', \'S3\', \'DOSpaces\', \'Backblaze\', \'Linode\' and \'Wasabi\'.', 'introduction' => '0.13.0', 'default' => 'Local', 'required' => false, 'question' => '', ], + [ + 'name' => '_APP_STORAGE_CONNECTION', + 'description' => 'A DSN representing the storage device to connect to. The DSN takes the following format ://:@:/?region=. For example, for S3: \'s3://access_key:access_secret@host:port/bucket?region=us-east-1\'. To use the local filesystem, you can leave this variable empty.', + 'introduction' => '1.1.0', + 'default' => '', + 'required' => false, + 'question' => '', + ], [ 'name' => '_APP_STORAGE_S3_ACCESS_KEY', - 'description' => 'AWS S3 storage access key. Required when the storage adapter is set to S3. You can get your access key from your AWS console', + 'description' => 'Deprecated since 1.1.0. AWS S3 storage access key. Required when the storage adapter is set to S3. You can get your access key from your AWS console', 'introduction' => '0.13.0', 'default' => '', 'required' => false, diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index f236285749..0436a5f5be 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -494,7 +494,7 @@ App::post('/v1/storage/buckets/:bucketId/files') } if ($chunksUploaded === $chunks) { - if (App::getEnv('_APP_STORAGE_ANTIVIRUS') === 'enabled' && $bucket->getAttribute('antivirus', true) && $fileSize <= APP_LIMIT_ANTIVIRUS && App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL) === Storage::DEVICE_LOCAL) { + if (App::getEnv('_APP_STORAGE_ANTIVIRUS') === 'enabled' && $bucket->getAttribute('antivirus', true) && $fileSize <= APP_LIMIT_ANTIVIRUS && App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL) === Storage::DEVICE_LOCAL) { // TODO : fetch from DSN $antivirus = new Network( App::getEnv('_APP_STORAGE_ANTIVIRUS_HOST', 'clamav'), (int) App::getEnv('_APP_STORAGE_ANTIVIRUS_PORT', 3310) diff --git a/app/executor.php b/app/executor.php index fba8c4c416..a09de2632b 100644 --- a/app/executor.php +++ b/app/executor.php @@ -13,6 +13,7 @@ use Swoole\Timer; use Utopia\App; use Utopia\CLI\Console; use Utopia\Database\DateTime; +use Utopia\DSN\DSN; use Utopia\Logger\Log; use Utopia\Logger\Logger; use Utopia\Orchestration\Adapter\DockerCLI; @@ -119,45 +120,35 @@ function logError(Throwable $error, string $action, Utopia\Route $route = null) function getStorageDevice($root): Device { - switch (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL)) { + $connection = App::getEnv('_APP_STORAGE_CONNECTION', ''); + + try { + $dsn = new DSN($connection); + $device = $dsn->getScheme(); + $accessKey = $dsn->getUser(); + $accessSecret = $dsn->getPassword(); + $bucket = $dsn->getPath(); + $region = $dsn->getParam('region'); + $acl = 'private'; + } catch (\Exception $e) { + Console::error($e->getMessage() . 'Defaulting to Local storage.'); + $device = 'Local'; + } + + switch ($device) { case Storage::DEVICE_LOCAL: default: return new Local($root); case Storage::DEVICE_S3: - $s3AccessKey = App::getEnv('_APP_STORAGE_S3_ACCESS_KEY', ''); - $s3SecretKey = App::getEnv('_APP_STORAGE_S3_SECRET', ''); - $s3Region = App::getEnv('_APP_STORAGE_S3_REGION', ''); - $s3Bucket = App::getEnv('_APP_STORAGE_S3_BUCKET', ''); - $s3Acl = 'private'; - return new S3($root, $s3AccessKey, $s3SecretKey, $s3Bucket, $s3Region, $s3Acl); + return new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_DO_SPACES: - $doSpacesAccessKey = App::getEnv('_APP_STORAGE_DO_SPACES_ACCESS_KEY', ''); - $doSpacesSecretKey = App::getEnv('_APP_STORAGE_DO_SPACES_SECRET', ''); - $doSpacesRegion = App::getEnv('_APP_STORAGE_DO_SPACES_REGION', ''); - $doSpacesBucket = App::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', ''); - $doSpacesAcl = 'private'; - return new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl); + return new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_BACKBLAZE: - $backblazeAccessKey = App::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', ''); - $backblazeSecretKey = App::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', ''); - $backblazeRegion = App::getEnv('_APP_STORAGE_BACKBLAZE_REGION', ''); - $backblazeBucket = App::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', ''); - $backblazeAcl = 'private'; - return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl); + return new Backblaze($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_LINODE: - $linodeAccessKey = App::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', ''); - $linodeSecretKey = App::getEnv('_APP_STORAGE_LINODE_SECRET', ''); - $linodeRegion = App::getEnv('_APP_STORAGE_LINODE_REGION', ''); - $linodeBucket = App::getEnv('_APP_STORAGE_LINODE_BUCKET', ''); - $linodeAcl = 'private'; - return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl); + return new Linode($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_WASABI: - $wasabiAccessKey = App::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', ''); - $wasabiSecretKey = App::getEnv('_APP_STORAGE_WASABI_SECRET', ''); - $wasabiRegion = App::getEnv('_APP_STORAGE_WASABI_REGION', ''); - $wasabiBucket = App::getEnv('_APP_STORAGE_WASABI_BUCKET', ''); - $wasabiAcl = 'private'; - return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl); + return new Wasabi($root, $accessKey, $accessSecret, $bucket, $region, $acl); } } diff --git a/app/init.php b/app/init.php index 054721d439..cde78c4ce9 100644 --- a/app/init.php +++ b/app/init.php @@ -29,7 +29,6 @@ use Appwrite\SMS\Adapter\TextMagic; use Appwrite\SMS\Adapter\Twilio; use Appwrite\SMS\Adapter\Msg91; use Appwrite\SMS\Adapter\Vonage; -use Appwrite\DSN\DSN; use Appwrite\Event\Audit; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Delete; @@ -63,8 +62,10 @@ use Swoole\Database\PDOConfig; use Swoole\Database\PDOPool; use Swoole\Database\RedisConfig; use Swoole\Database\RedisPool; +use Utopia\CLI\Console; use Utopia\Database\Query; use Utopia\Database\Validator\DatetimeValidator; +use Utopia\DSN\DSN; use Utopia\Storage\Device; use Utopia\Storage\Storage; use Utopia\Storage\Device\Backblaze; @@ -964,45 +965,35 @@ App::setResource('deviceBuilds', function ($project) { function getDevice($root): Device { - switch (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL)) { + $connection = App::getEnv('_APP_STORAGE_CONNECTION', ''); + + try { + $dsn = new DSN($connection); + $device = $dsn->getScheme(); + $accessKey = $dsn->getUser(); + $accessSecret = $dsn->getPassword(); + $bucket = $dsn->getPath(); + $region = $dsn->getParam('region'); + $acl = 'private'; + } catch (\Exception $e) { + Console::error($e->getMessage() . 'Defaulting to Local storage.'); + $device = 'Local'; + } + + switch ($device) { case Storage::DEVICE_LOCAL: default: return new Local($root); case Storage::DEVICE_S3: - $s3AccessKey = App::getEnv('_APP_STORAGE_S3_ACCESS_KEY', ''); - $s3SecretKey = App::getEnv('_APP_STORAGE_S3_SECRET', ''); - $s3Region = App::getEnv('_APP_STORAGE_S3_REGION', ''); - $s3Bucket = App::getEnv('_APP_STORAGE_S3_BUCKET', ''); - $s3Acl = 'private'; - return new S3($root, $s3AccessKey, $s3SecretKey, $s3Bucket, $s3Region, $s3Acl); + return new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_DO_SPACES: - $doSpacesAccessKey = App::getEnv('_APP_STORAGE_DO_SPACES_ACCESS_KEY', ''); - $doSpacesSecretKey = App::getEnv('_APP_STORAGE_DO_SPACES_SECRET', ''); - $doSpacesRegion = App::getEnv('_APP_STORAGE_DO_SPACES_REGION', ''); - $doSpacesBucket = App::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', ''); - $doSpacesAcl = 'private'; - return new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl); + return new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_BACKBLAZE: - $backblazeAccessKey = App::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', ''); - $backblazeSecretKey = App::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', ''); - $backblazeRegion = App::getEnv('_APP_STORAGE_BACKBLAZE_REGION', ''); - $backblazeBucket = App::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', ''); - $backblazeAcl = 'private'; - return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl); + return new Backblaze($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_LINODE: - $linodeAccessKey = App::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', ''); - $linodeSecretKey = App::getEnv('_APP_STORAGE_LINODE_SECRET', ''); - $linodeRegion = App::getEnv('_APP_STORAGE_LINODE_REGION', ''); - $linodeBucket = App::getEnv('_APP_STORAGE_LINODE_BUCKET', ''); - $linodeAcl = 'private'; - return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl); + return new Linode($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_WASABI: - $wasabiAccessKey = App::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', ''); - $wasabiSecretKey = App::getEnv('_APP_STORAGE_WASABI_SECRET', ''); - $wasabiRegion = App::getEnv('_APP_STORAGE_WASABI_REGION', ''); - $wasabiBucket = App::getEnv('_APP_STORAGE_WASABI_BUCKET', ''); - $wasabiAcl = 'private'; - return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl); + return new Wasabi($root, $accessKey, $accessSecret, $bucket, $region, $acl); } } diff --git a/app/workers/builds.php b/app/workers/builds.php index bf780c6464..f8ffb8a8f0 100644 --- a/app/workers/builds.php +++ b/app/workers/builds.php @@ -91,7 +91,7 @@ class BuildsV1 extends Worker 'outputPath' => '', 'runtime' => $function->getAttribute('runtime'), 'source' => $deployment->getAttribute('path'), - 'sourceType' => App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL), + 'sourceType' => App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL), // TODO : fetch from DSN 'stdout' => '', 'stderr' => '', 'endTime' => null, diff --git a/composer.json b/composer.json index 47317ed5e2..82149d15c3 100644 --- a/composer.json +++ b/composer.json @@ -57,6 +57,7 @@ "utopia-php/preloader": "0.2.*", "utopia-php/domains": "1.1.*", "utopia-php/swoole": "0.3.*", + "utopia-php/dsn": "dev-dev", "utopia-php/storage": "0.11.*", "utopia-php/websocket": "0.1.0", "utopia-php/image": "0.5.*", @@ -74,6 +75,10 @@ { "url": "https://github.com/appwrite/runtimes.git", "type": "git" + }, + { + "url": "https://github.com/utopia-php/dsn.git", + "type": "git" } ], "require-dev": { diff --git a/composer.lock b/composer.lock index f6f29452ad..3f3f4833b6 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": "08fdd139ad1285b02c4b4e555679e7de", + "content-hash": "b9786b80c04af9966f4d36c085dd4090", "packages": [ { "name": "adhocore/jwt", @@ -693,16 +693,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.4.1", + "version": "2.4.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" + "reference": "3148458748274be1546f8f2809a6c09fe66f44aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/3148458748274be1546f8f2809a6c09fe66f44aa", + "reference": "3148458748274be1546f8f2809a6c09fe66f44aa", "shasum": "" }, "require": { @@ -792,7 +792,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.1" + "source": "https://github.com/guzzle/psr7/tree/2.4.2" }, "funding": [ { @@ -808,7 +808,7 @@ "type": "tidelift" } ], - "time": "2022-08-28T14:45:39+00:00" + "time": "2022-10-25T13:49:28+00:00" }, { "name": "influxdb/influxdb-php", @@ -2170,6 +2170,53 @@ }, "time": "2020-02-23T07:40:02+00:00" }, + { + "name": "utopia-php/dsn", + "version": "dev-dev", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/dsn.git", + "reference": "9a524236c37474fcb121dc0d9eb13a0bcead9cf6" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\DSN\\": "src/DSN" + } + }, + "scripts": { + "lint": [ + "./vendor/bin/pint --test" + ], + "format": [ + "./vendor/bin/pint" + ], + "test": [ + "./vendor/bin/phpunit --configuration phpunit.xml tests" + ] + }, + "license": [ + "MIT" + ], + "description": "A simple library for parsing and managing Data Source Names ( DSNs )", + "keywords": [ + "dsn", + "framework", + "php", + "upf", + "utopia" + ], + "time": "2022-10-26T03:49:15+00:00" + }, { "name": "utopia-php/framework", "version": "0.21.1", @@ -5359,7 +5406,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/dsn": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/docker-compose.yml b/docker-compose.yml index ea9241a9d3..87bf5d5efb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -131,27 +131,7 @@ services: - _APP_STORAGE_ANTIVIRUS - _APP_STORAGE_ANTIVIRUS_HOST - _APP_STORAGE_ANTIVIRUS_PORT - - _APP_STORAGE_DEVICE - - _APP_STORAGE_S3_ACCESS_KEY - - _APP_STORAGE_S3_SECRET - - _APP_STORAGE_S3_REGION - - _APP_STORAGE_S3_BUCKET - - _APP_STORAGE_DO_SPACES_ACCESS_KEY - - _APP_STORAGE_DO_SPACES_SECRET - - _APP_STORAGE_DO_SPACES_REGION - - _APP_STORAGE_DO_SPACES_BUCKET - - _APP_STORAGE_BACKBLAZE_ACCESS_KEY - - _APP_STORAGE_BACKBLAZE_SECRET - - _APP_STORAGE_BACKBLAZE_REGION - - _APP_STORAGE_BACKBLAZE_BUCKET - - _APP_STORAGE_LINODE_ACCESS_KEY - - _APP_STORAGE_LINODE_SECRET - - _APP_STORAGE_LINODE_REGION - - _APP_STORAGE_LINODE_BUCKET - - _APP_STORAGE_WASABI_ACCESS_KEY - - _APP_STORAGE_WASABI_SECRET - - _APP_STORAGE_WASABI_REGION - - _APP_STORAGE_WASABI_BUCKET + - _APP_STORAGE_CONNECTION - _APP_FUNCTIONS_SIZE_LIMIT - _APP_FUNCTIONS_TIMEOUT - _APP_FUNCTIONS_BUILD_TIMEOUT @@ -304,27 +284,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_STORAGE_DEVICE - - _APP_STORAGE_S3_ACCESS_KEY - - _APP_STORAGE_S3_SECRET - - _APP_STORAGE_S3_REGION - - _APP_STORAGE_S3_BUCKET - - _APP_STORAGE_DO_SPACES_ACCESS_KEY - - _APP_STORAGE_DO_SPACES_SECRET - - _APP_STORAGE_DO_SPACES_REGION - - _APP_STORAGE_DO_SPACES_BUCKET - - _APP_STORAGE_BACKBLAZE_ACCESS_KEY - - _APP_STORAGE_BACKBLAZE_SECRET - - _APP_STORAGE_BACKBLAZE_REGION - - _APP_STORAGE_BACKBLAZE_BUCKET - - _APP_STORAGE_LINODE_ACCESS_KEY - - _APP_STORAGE_LINODE_SECRET - - _APP_STORAGE_LINODE_REGION - - _APP_STORAGE_LINODE_BUCKET - - _APP_STORAGE_WASABI_ACCESS_KEY - - _APP_STORAGE_WASABI_SECRET - - _APP_STORAGE_WASABI_REGION - - _APP_STORAGE_WASABI_BUCKET + - _APP_STORAGE_CONNECTION - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET @@ -492,27 +452,7 @@ services: - OPEN_RUNTIMES_NETWORK - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - - _APP_STORAGE_DEVICE - - _APP_STORAGE_S3_ACCESS_KEY - - _APP_STORAGE_S3_SECRET - - _APP_STORAGE_S3_REGION - - _APP_STORAGE_S3_BUCKET - - _APP_STORAGE_DO_SPACES_ACCESS_KEY - - _APP_STORAGE_DO_SPACES_SECRET - - _APP_STORAGE_DO_SPACES_REGION - - _APP_STORAGE_DO_SPACES_BUCKET - - _APP_STORAGE_BACKBLAZE_ACCESS_KEY - - _APP_STORAGE_BACKBLAZE_SECRET - - _APP_STORAGE_BACKBLAZE_REGION - - _APP_STORAGE_BACKBLAZE_BUCKET - - _APP_STORAGE_LINODE_ACCESS_KEY - - _APP_STORAGE_LINODE_SECRET - - _APP_STORAGE_LINODE_REGION - - _APP_STORAGE_LINODE_BUCKET - - _APP_STORAGE_WASABI_ACCESS_KEY - - _APP_STORAGE_WASABI_SECRET - - _APP_STORAGE_WASABI_REGION - - _APP_STORAGE_WASABI_BUCKET + - _APP_STORAGE_CONNECTION - DOCKERHUB_PULL_USERNAME - DOCKERHUB_PULL_PASSWORD diff --git a/src/Appwrite/DSN/DSN.php b/src/Appwrite/DSN/DSN.php deleted file mode 100644 index 5605640989..0000000000 --- a/src/Appwrite/DSN/DSN.php +++ /dev/null @@ -1,135 +0,0 @@ -scheme = $parts['scheme'] ?? null; - $this->user = $parts['user'] ?? null; - $this->password = $parts['pass'] ?? null; - $this->host = $parts['host'] ?? null; - $this->port = $parts['port'] ?? null; - $this->database = $parts['path'] ?? null; - $this->query = $parts['query'] ?? null; - } - - /** - * Return the scheme. - * - * @return string - */ - public function getScheme(): string - { - return $this->scheme; - } - - /** - * Return the user. - * - * @return ?string - */ - public function getUser(): ?string - { - return $this->user; - } - - /** - * Return the password. - * - * @return ?string - */ - public function getPassword(): ?string - { - return $this->password; - } - - /** - * Return the host - * - * @return string - */ - public function getHost(): string - { - return $this->host; - } - - /** - * Return the port - * - * @return ?string - */ - public function getPort(): ?string - { - return $this->port; - } - - /** - * Return the database - * - * @return ?string - */ - public function getDatabase(): ?string - { - return ltrim($this->database, '/'); - } - - /** - * Return the query string - * - * @return ?string - */ - public function getQuery(): ?string - { - return $this->query; - } -} diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index dd7cebd084..c6e5e90c5e 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -18,6 +18,7 @@ use Utopia\Storage\Device\Backblaze; use Utopia\Storage\Device\S3; use Exception; use Utopia\Database\Validator\Authorization; +use Utopia\DSN\DSN; abstract class Worker { @@ -284,45 +285,35 @@ abstract class Worker */ public function getDevice($root): Device { - switch (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL)) { + $connection = App::getEnv('_APP_STORAGE_CONNECTION', ''); + + try { + $dsn = new DSN($connection); + $device = $dsn->getScheme(); + $accessKey = $dsn->getUser(); + $accessSecret = $dsn->getPassword(); + $bucket = $dsn->getPath(); + $region = $dsn->getParam('region'); + $acl = 'private'; + } catch (\Exception $e) { + Console::error($e->getMessage() . 'Defaulting to Local storage.'); + $device = 'Local'; + } + + switch ($device) { + case Storage::DEVICE_S3: + return new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl); + case Storage::DEVICE_DO_SPACES: + return new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl); + case Storage::DEVICE_BACKBLAZE: + return new Backblaze($root, $accessKey, $accessSecret, $bucket, $region, $acl); + case Storage::DEVICE_LINODE: + return new Linode($root, $accessKey, $accessSecret, $bucket, $region, $acl); + case Storage::DEVICE_WASABI: + return new Wasabi($root, $accessKey, $accessSecret, $bucket, $region, $acl); case Storage::DEVICE_LOCAL: default: return new Local($root); - case Storage::DEVICE_S3: - $s3AccessKey = App::getEnv('_APP_STORAGE_S3_ACCESS_KEY', ''); - $s3SecretKey = App::getEnv('_APP_STORAGE_S3_SECRET', ''); - $s3Region = App::getEnv('_APP_STORAGE_S3_REGION', ''); - $s3Bucket = App::getEnv('_APP_STORAGE_S3_BUCKET', ''); - $s3Acl = 'private'; - return new S3($root, $s3AccessKey, $s3SecretKey, $s3Bucket, $s3Region, $s3Acl); - case Storage::DEVICE_DO_SPACES: - $doSpacesAccessKey = App::getEnv('_APP_STORAGE_DO_SPACES_ACCESS_KEY', ''); - $doSpacesSecretKey = App::getEnv('_APP_STORAGE_DO_SPACES_SECRET', ''); - $doSpacesRegion = App::getEnv('_APP_STORAGE_DO_SPACES_REGION', ''); - $doSpacesBucket = App::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', ''); - $doSpacesAcl = 'private'; - return new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl); - case Storage::DEVICE_BACKBLAZE: - $backblazeAccessKey = App::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', ''); - $backblazeSecretKey = App::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', ''); - $backblazeRegion = App::getEnv('_APP_STORAGE_BACKBLAZE_REGION', ''); - $backblazeBucket = App::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', ''); - $backblazeAcl = 'private'; - return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl); - case Storage::DEVICE_LINODE: - $linodeAccessKey = App::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', ''); - $linodeSecretKey = App::getEnv('_APP_STORAGE_LINODE_SECRET', ''); - $linodeRegion = App::getEnv('_APP_STORAGE_LINODE_REGION', ''); - $linodeBucket = App::getEnv('_APP_STORAGE_LINODE_BUCKET', ''); - $linodeAcl = 'private'; - return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl); - case Storage::DEVICE_WASABI: - $wasabiAccessKey = App::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', ''); - $wasabiSecretKey = App::getEnv('_APP_STORAGE_WASABI_SECRET', ''); - $wasabiRegion = App::getEnv('_APP_STORAGE_WASABI_REGION', ''); - $wasabiBucket = App::getEnv('_APP_STORAGE_WASABI_BUCKET', ''); - $wasabiAcl = 'private'; - return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl); } } } diff --git a/tests/unit/DSN/DSNTest.php b/tests/unit/DSN/DSNTest.php deleted file mode 100644 index d1f5ba1197..0000000000 --- a/tests/unit/DSN/DSNTest.php +++ /dev/null @@ -1,81 +0,0 @@ -assertEquals("mariadb", $dsn->getScheme()); - $this->assertEquals("user", $dsn->getUser()); - $this->assertEquals("password", $dsn->getPassword()); - $this->assertEquals("localhost", $dsn->getHost()); - $this->assertEquals("3306", $dsn->getPort()); - $this->assertEquals("database", $dsn->getDatabase()); - $this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery()); - - $dsn = new DSN("mariadb://user@localhost:3306/database?charset=utf8&timezone=UTC"); - $this->assertEquals("mariadb", $dsn->getScheme()); - $this->assertEquals("user", $dsn->getUser()); - $this->assertNull($dsn->getPassword()); - $this->assertEquals("localhost", $dsn->getHost()); - $this->assertEquals("3306", $dsn->getPort()); - $this->assertEquals("database", $dsn->getDatabase()); - $this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery()); - - $dsn = new DSN("mariadb://user@localhost/database?charset=utf8&timezone=UTC"); - $this->assertEquals("mariadb", $dsn->getScheme()); - $this->assertEquals("user", $dsn->getUser()); - $this->assertNull($dsn->getPassword()); - $this->assertEquals("localhost", $dsn->getHost()); - $this->assertNull($dsn->getPort()); - $this->assertEquals("database", $dsn->getDatabase()); - $this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery()); - - $dsn = new DSN("mariadb://user@localhost?charset=utf8&timezone=UTC"); - $this->assertEquals("mariadb", $dsn->getScheme()); - $this->assertEquals("user", $dsn->getUser()); - $this->assertNull($dsn->getPassword()); - $this->assertEquals("localhost", $dsn->getHost()); - $this->assertNull($dsn->getPort()); - $this->assertEmpty($dsn->getDatabase()); - $this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery()); - - $dsn = new DSN("mariadb://user@localhost"); - $this->assertEquals("mariadb", $dsn->getScheme()); - $this->assertEquals("user", $dsn->getUser()); - $this->assertNull($dsn->getPassword()); - $this->assertEquals("localhost", $dsn->getHost()); - $this->assertNull($dsn->getPort()); - $this->assertEmpty($dsn->getDatabase()); - $this->assertNull($dsn->getQuery()); - - $dsn = new DSN("mariadb://user:@localhost"); - $this->assertEquals("mariadb", $dsn->getScheme()); - $this->assertEquals("user", $dsn->getUser()); - $this->assertEmpty($dsn->getPassword()); - $this->assertEquals("localhost", $dsn->getHost()); - $this->assertNull($dsn->getPort()); - $this->assertEmpty($dsn->getDatabase()); - $this->assertNull($dsn->getQuery()); - - $dsn = new DSN("mariadb://localhost"); - $this->assertEquals("mariadb", $dsn->getScheme()); - $this->assertNull($dsn->getUser()); - $this->assertNull($dsn->getPassword()); - $this->assertEquals("localhost", $dsn->getHost()); - $this->assertNull($dsn->getPort()); - $this->assertEmpty($dsn->getDatabase()); - $this->assertNull($dsn->getQuery()); - } - - public function testFail(): void - { - $this->expectException(\InvalidArgumentException::class); - new DSN("mariadb://"); - } -}