From 5a7c43ab32f352bb3424f39b7e67e93b0b4796ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 7 Mar 2024 10:59:08 +0100 Subject: [PATCH] Introduce code analysis --- .github/workflows/codeql-phpstan.yml | 16 +++++ app/cli.php | 2 + app/init.php | 2 - app/worker.php | 2 + composer.json | 6 +- composer.lock | 61 ++++++++++++++++++- phpstan.neon | 11 ++++ src/Appwrite/Auth/OAuth2/Autodesk.php | 2 +- src/Appwrite/Event/Func.php | 4 +- src/Appwrite/Platform/Tasks/SDKs.php | 4 +- src/Appwrite/Platform/Workers/Builds.php | 14 ++--- src/Appwrite/Platform/Workers/Messaging.php | 4 +- src/Appwrite/Promises/Promise.php | 2 +- src/Appwrite/Promises/Swoole.php | 5 -- .../Specification/Format/OpenAPI3.php | 7 ++- src/Appwrite/Utopia/Request/Filters/V14.php | 3 + src/Appwrite/Utopia/Response/Filters/V11.php | 1 + src/Appwrite/Utopia/Response/Filters/V12.php | 2 - .../Services/GraphQL/StorageClientTest.php | 1 - .../Services/GraphQL/StorageServerTest.php | 1 - 20 files changed, 119 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/codeql-phpstan.yml create mode 100644 phpstan.neon diff --git a/.github/workflows/codeql-phpstan.yml b/.github/workflows/codeql-phpstan.yml new file mode 100644 index 000000000..3253e2c38 --- /dev/null +++ b/.github/workflows/codeql-phpstan.yml @@ -0,0 +1,16 @@ +name: "CodeQL" + +on: [pull_request] +jobs: + lint: + name: CodeQL + runs-on: ubuntu-latest + + steps: + - name: Check out the repo + uses: actions/checkout@v2 + + - name: Run CodeQL + run: | + docker run --rm -v $PWD:/app composer sh -c \ + "composer install --profile --ignore-platform-reqs && composer check" \ No newline at end of file diff --git a/app/cli.php b/app/cli.php index 1a8c785a3..11b952dad 100644 --- a/app/cli.php +++ b/app/cli.php @@ -23,6 +23,8 @@ use Utopia\Pools\Group; use Utopia\Queue\Connection; use Utopia\Registry\Registry; +global $register; + Authorization::disable(); CLI::setResource('register', fn () => $register); diff --git a/app/init.php b/app/init.php index 8f8bdb9c6..c06820961 100644 --- a/app/init.php +++ b/app/init.php @@ -48,7 +48,6 @@ use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; use Utopia\CLI\Console; -use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Adapter\MariaDBProxy; @@ -62,7 +61,6 @@ use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Structure; use Utopia\Domains\Validator\PublicDomain; -use Utopia\Domains\Validator\PublicDomain; use Utopia\DSN\DSN; use Utopia\Locale\Locale; use Utopia\Logger\Log; diff --git a/app/worker.php b/app/worker.php index 98a1e40a8..8523b81cd 100644 --- a/app/worker.php +++ b/app/worker.php @@ -36,6 +36,8 @@ use Utopia\Queue\Server; use Utopia\Registry\Registry; use Utopia\Storage\Device\Local; +global $register; + Authorization::disable(); Runtime::enableCoroutine(SWOOLE_HOOK_ALL); diff --git a/composer.json b/composer.json index ad1783125..96bf4dba4 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "scripts": { "test": "vendor/bin/phpunit", "lint": "vendor/bin/pint --test", - "format": "vendor/bin/pint" + "format": "vendor/bin/pint", + "check": "./vendor/bin/phpstan analyse -c phpstan.neon --memory-limit 1G app src tests" }, "autoload": { "psr-4": { @@ -84,7 +85,8 @@ "swoole/ide-helper": "5.0.2", "textalk/websocket": "1.5.7", "utopia-php/fetch": "0.1.*", - "laravel/pint": "^1.14" + "laravel/pint": "^1.14", + "phpstan/phpstan": "1.8.*" }, "provide": { "ext-phpiredis": "*" diff --git a/composer.lock b/composer.lock index 0f0285994..801b87c53 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": "03de7dbb57fcecac386e5b710ec5fe49", + "content-hash": "1c3c0b518e1486c5770b57519da2a797", "packages": [ { "name": "adhocore/jwt", @@ -3642,6 +3642,65 @@ }, "time": "2024-02-23T16:05:55+00:00" }, + { + "name": "phpstan/phpstan", + "version": "1.8.11", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "46e223dd68a620da18855c23046ddb00940b4014" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/46e223dd68a620da18855c23046ddb00940b4014", + "reference": "46e223dd68a620da18855c23046ddb00940b4014", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.8.11" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-10-24T15:45:13+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "9.2.31", diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 000000000..25771ef17 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,11 @@ +parameters: + level: 0 + scanDirectories: + - vendor/swoole/ide-helper + excludePaths: + - tests/resources + ignoreErrors: + - '#Parameter \$geodb of anonymous function has invalid type MaxMind\\Db\\Reader\.#' + - '#Parameter \$geodb of function router\(\) has invalid type MaxMind\\Db\\Reader\.#' + - '#Instantiated class MaxMind\\Db\\Reader not found.#' + - '#Function scrypt not found\.#' diff --git a/src/Appwrite/Auth/OAuth2/Autodesk.php b/src/Appwrite/Auth/OAuth2/Autodesk.php index 0b268ead3..9d9979196 100644 --- a/src/Appwrite/Auth/OAuth2/Autodesk.php +++ b/src/Appwrite/Auth/OAuth2/Autodesk.php @@ -88,7 +88,7 @@ class Autodesk extends OAuth2 'client_id' => $this->appID, 'client_secret' => $this->appSecret, 'grant_type' => 'refresh_token', - 'code' => $code, + 'code' => $refreshToken, 'redirect_uri' => $this->callback, ]) ); diff --git a/src/Appwrite/Event/Func.php b/src/Appwrite/Event/Func.php index 11c9e980e..bdc5cd7cc 100644 --- a/src/Appwrite/Event/Func.php +++ b/src/Appwrite/Event/Func.php @@ -152,9 +152,9 @@ class Func extends Event * * @return string */ - public function getData(): string + public function getBody(): string { - return $this->data; + return $this->body; } /** diff --git a/src/Appwrite/Platform/Tasks/SDKs.php b/src/Appwrite/Platform/Tasks/SDKs.php index 014e33109..b3fb96808 100644 --- a/src/Appwrite/Platform/Tasks/SDKs.php +++ b/src/Appwrite/Platform/Tasks/SDKs.php @@ -50,7 +50,7 @@ class SDKs extends Action $message = ($git) ? Console::confirm('Please enter your commit message:') : ''; if (!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x', '0.10.x', '0.11.x', '0.12.x', '0.13.x', '0.14.x', '0.15.x', '1.0.x', '1.1.x', '1.2.x', '1.3.x', '1.4.x', '1.5.x', 'latest'])) { - throw new Exception('Unknown version given'); + throw new \Exception('Unknown version given'); } foreach ($platforms as $key => $platform) { @@ -196,7 +196,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND $config = new REST(); break; default: - throw new Exception('Language "' . $language['key'] . '" not supported'); + throw new \Exception('Language "' . $language['key'] . '" not supported'); } Console::info("Generating {$language['name']} SDK..."); diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index b9f02a8f6..31bf961c3 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -73,7 +73,7 @@ class Builds extends Action $payload = $message->getPayload() ?? []; if (empty($payload)) { - throw new Exception('Missing payload'); + throw new \Exception('Missing payload'); } $type = $payload['type'] ?? ''; @@ -124,7 +124,7 @@ class Builds extends Action $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new \Exception('Function not found', 404); } $deploymentId = $deployment->getId(); @@ -132,11 +132,11 @@ class Builds extends Action $deployment = $dbForProject->getDocument('deployments', $deploymentId); if ($deployment->isEmpty()) { - throw new Exception('Deployment not found', 404); + throw new \Exception('Deployment not found', 404); } if (empty($deployment->getAttribute('entrypoint', ''))) { - throw new Exception('Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".', 500); + throw new \Exception('Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".', 500); } $version = $function->getAttribute('version', 'v2'); @@ -144,7 +144,7 @@ class Builds extends Action $key = $function->getAttribute('runtime'); $runtime = $runtimes[$key] ?? null; if (\is_null($runtime)) { - throw new Exception('Runtime "' . $function->getAttribute('runtime', '') . '" is not supported'); + throw new \Exception('Runtime "' . $function->getAttribute('runtime', '') . '" is not supported'); } // Realtime preparation @@ -306,7 +306,7 @@ class Builds extends Action $directorySize = $localDevice->getDirectorySize($tmpDirectory); $functionsSizeLimit = (int) App::getEnv('_APP_FUNCTIONS_SIZE_LIMIT', '30000000'); if ($directorySize > $functionsSizeLimit) { - throw new Exception('Repository directory size should be less than ' . number_format($functionsSizeLimit / 1048576, 2) . ' MBs.'); + throw new \Exception('Repository directory size should be less than ' . number_format($functionsSizeLimit / 1048576, 2) . ' MBs.'); } Console::execute('tar --exclude code.tar.gz -czf ' . $tmpPathFile . ' -C /tmp/builds/' . \escapeshellcmd($buildId) . '/code' . (empty($rootDirectory) ? '' : '/' . $rootDirectory) . ' .', '', $stdout, $stderr); @@ -431,7 +431,7 @@ class Builds extends Action $build = $dbForProject->getDocument('builds', $build->getId()); if ($build->isEmpty()) { - throw new Exception('Build not found', 404); + throw new \Exception('Build not found', 404); } $build = $build->setAttribute('logs', $build->getAttribute('logs', '') . $logs); diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 6ebedd41a..e94f9b495 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -25,7 +25,7 @@ use Utopia\Messaging\Adapter\SMS as SMSAdapter; use Utopia\Messaging\Adapter\SMS\Mock; use Utopia\Messaging\Adapter\SMS\Msg91; use Utopia\Messaging\Adapter\SMS\Telesign; -use Utopia\Messaging\Adapter\SMS\Textmagic; +use Utopia\Messaging\Adapter\SMS\TextMagic; use Utopia\Messaging\Adapter\SMS\Twilio; use Utopia\Messaging\Adapter\SMS\Vonage; use Utopia\Messaging\Messages\Email; @@ -456,7 +456,7 @@ class Messaging extends Action return match ($provider->getAttribute('provider')) { 'mock' => new Mock('username', 'password'), 'twilio' => new Twilio($credentials['accountSid'], $credentials['authToken']), - 'textmagic' => new Textmagic($credentials['username'], $credentials['apiKey']), + 'textmagic' => new TextMagic($credentials['username'], $credentials['apiKey']), 'telesign' => new Telesign($credentials['customerId'], $credentials['apiKey']), 'msg91' => new Msg91($credentials['senderId'], $credentials['authKey'], $credentials['templateId']), 'vonage' => new Vonage($credentials['apiKey'], $credentials['apiSecret']), diff --git a/src/Appwrite/Promises/Promise.php b/src/Appwrite/Promises/Promise.php index a6b1aa79d..f12590dfe 100644 --- a/src/Appwrite/Promises/Promise.php +++ b/src/Appwrite/Promises/Promise.php @@ -12,7 +12,7 @@ abstract class Promise private mixed $result; - public function __construct(?callable $executor = null) + final public function __construct(?callable $executor = null) { if (\is_null($executor)) { return; diff --git a/src/Appwrite/Promises/Swoole.php b/src/Appwrite/Promises/Swoole.php index c258ef6a5..d0b3eb885 100644 --- a/src/Appwrite/Promises/Swoole.php +++ b/src/Appwrite/Promises/Swoole.php @@ -6,11 +6,6 @@ use Swoole\Coroutine\Channel; class Swoole extends Promise { - public function __construct(?callable $executor = null) - { - parent::__construct($executor); - } - protected function execute( callable $executor, callable $resolve, diff --git a/src/Appwrite/Specification/Format/OpenAPI3.php b/src/Appwrite/Specification/Format/OpenAPI3.php index bc85d8e50..4442dd9a0 100644 --- a/src/Appwrite/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/Specification/Format/OpenAPI3.php @@ -238,8 +238,11 @@ class OpenAPI3 extends Format } if ($route->getLabel('sdk.response.code', 500) === 204) { - $temp['responses'][(string)$route->getLabel('sdk.response.code', '500')]['description'] = 'No content'; - unset($temp['responses'][(string)$route->getLabel('sdk.response.code', '500')]['schema']); + $labelCode = (string)$route->getLabel('sdk.response.code', '500'); + $temp['responses'][$labelCode]['description'] = 'No content'; + if(isset($temp['responses'][$labelCode]['schema'])) { + unset($temp['responses'][$labelCode]['schema']); + } } if ((!empty($scope))) { // && 'public' != $scope diff --git a/src/Appwrite/Utopia/Request/Filters/V14.php b/src/Appwrite/Utopia/Request/Filters/V14.php index f42a35102..40fd3ebe8 100644 --- a/src/Appwrite/Utopia/Request/Filters/V14.php +++ b/src/Appwrite/Utopia/Request/Filters/V14.php @@ -24,11 +24,14 @@ class V14 extends Filter private function convertEvents($content) { + // TODO: If nessessary, implement V13 and use following code: + /* $migration = new MigrationV13(); $events = $content['events'] ?? []; $content['events'] = $migration->migrateEvents($events); return $content; + */ } } diff --git a/src/Appwrite/Utopia/Response/Filters/V11.php b/src/Appwrite/Utopia/Response/Filters/V11.php index 9d6459915..941c1e1d2 100644 --- a/src/Appwrite/Utopia/Response/Filters/V11.php +++ b/src/Appwrite/Utopia/Response/Filters/V11.php @@ -2,6 +2,7 @@ namespace Appwrite\Utopia\Response\Filters; +use Appwrite\ID; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Filter; diff --git a/src/Appwrite/Utopia/Response/Filters/V12.php b/src/Appwrite/Utopia/Response/Filters/V12.php index 79d22ad04..c4ffcfef5 100644 --- a/src/Appwrite/Utopia/Response/Filters/V12.php +++ b/src/Appwrite/Utopia/Response/Filters/V12.php @@ -209,8 +209,6 @@ class V12 extends Filter unset($content['bucketsRead']); unset($content['bucketsUpdate']); unset($content['bucketsDelete']); - unset($content['filesCount']); - unset($content['bucketsDelete']); unset($content['filesCreate']); unset($content['filesRead']); unset($content['filesUpdate']); diff --git a/tests/e2e/Services/GraphQL/StorageClientTest.php b/tests/e2e/Services/GraphQL/StorageClientTest.php index 9896598c2..7d6d617c8 100644 --- a/tests/e2e/Services/GraphQL/StorageClientTest.php +++ b/tests/e2e/Services/GraphQL/StorageClientTest.php @@ -183,7 +183,6 @@ class StorageClientTest extends Scope /** * @depends testCreateFile * @param $file - * @return array * @throws \Exception */ public function testGetFileDownload($file) diff --git a/tests/e2e/Services/GraphQL/StorageServerTest.php b/tests/e2e/Services/GraphQL/StorageServerTest.php index 7fea895b1..6be103629 100644 --- a/tests/e2e/Services/GraphQL/StorageServerTest.php +++ b/tests/e2e/Services/GraphQL/StorageServerTest.php @@ -232,7 +232,6 @@ class StorageServerTest extends Scope /** * @depends testCreateFile * @param $file - * @return array * @throws \Exception */ public function testGetFileDownload($file)