diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3513676a0..9df7dd899 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: - db_system: postgres steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Start Hashtopolis server uses: ./.github/actions/start-hashtopolis with: diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index 5a7727326..30b4bd52b 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 93f1f22af..c48e26091 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Python diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 000000000..9ea43ef2f --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,32 @@ +name: PHPStan + +on: + push: + branches: + - master + - dev + pull_request: + branches: + - master + - dev + +jobs: + phpstan: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.5' + tools: composer + coverage: none + + - name: Install dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + - name: Run PHPStan + run: vendor/bin/phpstan analyse \ No newline at end of file diff --git a/composer.json b/composer.json index 53728bde6..f3ad2af72 100644 --- a/composer.json +++ b/composer.json @@ -32,10 +32,9 @@ "tuupola/slim-basic-auth": "^3.3" }, "require-dev": { - "jangregor/phpstan-prophecy": "^1.0.0", "phpspec/prophecy-phpunit": "^2.0", "phpstan/extension-installer": "^1.1.0", - "phpstan/phpstan": "^1.8", + "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^9.5.25", "squizlabs/php_codesniffer": "^3.7" }, diff --git a/composer.lock b/composer.lock index e66c83657..e65baa43c 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": "6f8ce7872d6f4bc07dc58f3b9d468d4d", + "content-hash": "05373de718f2b591023edb0d6a9b2628", "packages": [ { "name": "composer/semver", @@ -85,27 +85,27 @@ }, { "name": "crell/api-problem", - "version": "3.7.0", + "version": "3.7.1", "source": { "type": "git", "url": "https://github.com/Crell/ApiProblem.git", - "reference": "b41d66dc1d403b2d406699e2e05bb2b48efe3b7f" + "reference": "3b52858d05736b68f08dd1e48e4235362de22831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Crell/ApiProblem/zipball/b41d66dc1d403b2d406699e2e05bb2b48efe3b7f", - "reference": "b41d66dc1d403b2d406699e2e05bb2b48efe3b7f", + "url": "https://api.github.com/repos/Crell/ApiProblem/zipball/3b52858d05736b68f08dd1e48e4235362de22831", + "reference": "3b52858d05736b68f08dd1e48e4235362de22831", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, "require-dev": { - "nyholm/psr7": "^1.8", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "psr/http-factory": "^1.0", - "psr/http-message": "1.*" + "nyholm/psr7": "^1.8.2", + "phpstan/phpstan": "^2.1.33", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.6.31", + "psr/http-factory": "^1.1", + "psr/http-message": "^1.1" }, "suggest": { "psr/http-factory": "Common interfaces for PSR-7 HTTP message factories", @@ -144,7 +144,7 @@ ], "support": { "issues": "https://github.com/Crell/ApiProblem/issues", - "source": "https://github.com/Crell/ApiProblem/tree/3.7.0" + "source": "https://github.com/Crell/ApiProblem/tree/3.7.1" }, "funding": [ { @@ -152,7 +152,7 @@ "type": "github" } ], - "time": "2024-09-30T22:47:27+00:00" + "time": "2026-01-12T20:12:58+00:00" }, { "name": "fig/http-message-util", @@ -579,16 +579,16 @@ }, { "name": "monolog/monolog", - "version": "2.10.0", + "version": "2.11.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "5cf826f2991858b54d5c3809bee745560a1042a7" + "reference": "37308608e599f34a1a4845b16440047ec98a172a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5cf826f2991858b54d5c3809bee745560a1042a7", - "reference": "5cf826f2991858b54d5c3809bee745560a1042a7", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/37308608e599f34a1a4845b16440047ec98a172a", + "reference": "37308608e599f34a1a4845b16440047ec98a172a", "shasum": "" }, "require": { @@ -606,7 +606,7 @@ "graylog2/gelf-php": "^1.4.2 || ^2@dev", "guzzlehttp/guzzle": "^7.4", "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8", + "mongodb/mongodb": "^1.8 || ^2.0", "php-amqplib/php-amqplib": "~2.4 || ^3", "phpspec/prophecy": "^1.15", "phpstan/phpstan": "^1.10", @@ -665,7 +665,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.10.0" + "source": "https://github.com/Seldaek/monolog/tree/2.11.0" }, "funding": [ { @@ -677,7 +677,7 @@ "type": "tidelift" } ], - "time": "2024-11-12T12:43:37+00:00" + "time": "2026-01-01T13:05:00+00:00" }, { "name": "nikic/fast-route", @@ -1718,30 +1718,29 @@ }, { "name": "doctrine/instantiator", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/23da848e1a2308728fe5fdddabf4be17ff9720c7", + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.4" }, "require-dev": { - "doctrine/coding-standard": "^11", + "doctrine/coding-standard": "^14", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5.27", - "vimeo/psalm": "^5.4" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5.58" }, "type": "library", "autoload": { @@ -1768,7 +1767,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + "source": "https://github.com/doctrine/instantiator/tree/2.1.0" }, "funding": [ { @@ -1784,66 +1783,7 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:23:10+00:00" - }, - { - "name": "jangregor/phpstan-prophecy", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/Jan0707/phpstan-prophecy.git", - "reference": "5ee56c7db1d58f0578c82a35e3c1befe840e85a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jan0707/phpstan-prophecy/zipball/5ee56c7db1d58f0578c82a35e3c1befe840e85a9", - "reference": "5ee56c7db1d58f0578c82a35e3c1befe840e85a9", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "phpstan/phpstan": "^1.0.0" - }, - "conflict": { - "phpspec/prophecy": "<1.7.0 || >=2.0.0", - "phpunit/phpunit": "<6.0.0 || >=12.0.0" - }, - "require-dev": { - "ergebnis/composer-normalize": "^2.1.1", - "ergebnis/license": "^1.0.0", - "ergebnis/php-cs-fixer-config": "~2.2.0", - "phpspec/prophecy": "^1.7.0", - "phpunit/phpunit": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "autoload": { - "psr-4": { - "JanGregor\\Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Gregor Emge-Triebel", - "email": "jan@jangregor.me" - } - ], - "description": "Provides a phpstan/phpstan extension for phpspec/prophecy", - "support": { - "issues": "https://github.com/Jan0707/phpstan-prophecy/issues", - "source": "https://github.com/Jan0707/phpstan-prophecy/tree/1.0.2" - }, - "time": "2024-04-03T08:15:54+00:00" + "time": "2026-01-05T06:47:08+00:00" }, { "name": "myclabs/deep-copy", @@ -2136,16 +2076,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.5", + "version": "5.6.6", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761" + "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/90614c73d3800e187615e2dd236ad0e2a01bf761", - "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8", "shasum": "" }, "require": { @@ -2155,7 +2095,7 @@ "phpdocumentor/reflection-common": "^2.2", "phpdocumentor/type-resolver": "^1.7", "phpstan/phpdoc-parser": "^1.7|^2.0", - "webmozart/assert": "^1.9.1" + "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { "mockery/mockery": "~1.3.5 || ~1.6.0", @@ -2194,9 +2134,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.5" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6" }, - "time": "2025-11-27T19:50:05+00:00" + "time": "2025-12-22T21:13:58+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -2432,16 +2372,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.3.0", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", "shasum": "" }, "require": { @@ -2473,21 +2413,21 @@ "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/2.3.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" }, - "time": "2025-08-30T15:50:23+00:00" + "time": "2026-01-25T14:56:51+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.32", + "version": "2.1.37", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/2770dcdf5078d0b0d53f94317e06affe88419aa8", - "reference": "2770dcdf5078d0b0d53f94317e06affe88419aa8", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/28cd424c5ea984128c95cfa7ea658808e8954e49", + "reference": "28cd424c5ea984128c95cfa7ea658808e8954e49", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -2528,7 +2468,7 @@ "type": "github" } ], - "time": "2025-09-30T10:16:31+00:00" + "time": "2026-01-24T08:21:55+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2851,16 +2791,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.31", + "version": "9.6.34", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "945d0b7f346a084ce5549e95289962972c4272e5" + "reference": "b36f02317466907a230d3aa1d34467041271ef4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/945d0b7f346a084ce5549e95289962972c4272e5", - "reference": "945d0b7f346a084ce5549e95289962972c4272e5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a", + "reference": "b36f02317466907a230d3aa1d34467041271ef4a", "shasum": "" }, "require": { @@ -2882,7 +2822,7 @@ "phpunit/php-timer": "^5.0.3", "sebastian/cli-parser": "^1.0.2", "sebastian/code-unit": "^1.0.8", - "sebastian/comparator": "^4.0.9", + "sebastian/comparator": "^4.0.10", "sebastian/diff": "^4.0.6", "sebastian/environment": "^5.1.5", "sebastian/exporter": "^4.0.8", @@ -2934,7 +2874,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.31" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34" }, "funding": [ { @@ -2958,7 +2898,7 @@ "type": "tidelift" } ], - "time": "2025-12-06T07:45:52+00:00" + "time": "2026-01-27T05:45:00+00:00" }, { "name": "sebastian/cli-parser", @@ -3129,16 +3069,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.9", + "version": "4.0.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5" + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5", - "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d", + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d", "shasum": "" }, "require": { @@ -3191,7 +3131,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10" }, "funding": [ { @@ -3211,7 +3151,7 @@ "type": "tidelift" } ], - "time": "2025-08-10T06:51:50+00:00" + "time": "2026-01-24T09:22:56+00:00" }, { "name": "sebastian/complexity", @@ -4169,23 +4109,23 @@ }, { "name": "webmozart/assert", - "version": "1.12.1", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + "reference": "ce6a2f100c404b2d32a1dd1270f9b59ad4f57649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/ce6a2f100c404b2d32a1dd1270f9b59ad4f57649", + "reference": "ce6a2f100c404b2d32a1dd1270f9b59ad4f57649", "shasum": "" }, "require": { "ext-ctype": "*", "ext-date": "*", "ext-filter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.2" }, "suggest": { "ext-intl": "", @@ -4195,7 +4135,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10-dev" + "dev-feature/2-0": "2.0-dev" } }, "autoload": { @@ -4211,6 +4151,10 @@ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", @@ -4221,9 +4165,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.12.1" + "source": "https://github.com/webmozarts/assert/tree/2.1.2" }, - "time": "2025-10-29T15:56:20+00:00" + "time": "2026-01-13T14:02:24+00:00" } ], "aliases": [], diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 000000000..3d3f345fd --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + paths: + - src/inc/apiv2 + level: 4 + scanDirectories: + - src/dba + - src/inc \ No newline at end of file diff --git a/src/inc/apiv2/auth/token.routes.php b/src/inc/apiv2/auth/token.routes.php index ac1f6c12c..b394d2cbc 100644 --- a/src/inc/apiv2/auth/token.routes.php +++ b/src/inc/apiv2/auth/token.routes.php @@ -16,6 +16,9 @@ function generateTokenForUser(Request $request, string $userName, int $expires) { include(dirname(__FILE__) . '/../../confv2.php'); + if (!isset($PEPPER)) { + throw new HttpError("Pepper is not set"); + } $jti = bin2hex(random_bytes(16)); $requested_scopes = $request->getParsedBody() ?: ["todo.all"]; @@ -74,6 +77,8 @@ function extractBearerToken(Request $request): ?string { } // Exchanges an oauth token for a application JWT token +use Slim\App; +/** @var App $app */ $app->group("/api/v2/auth/oauth-token", function (RouteCollectorProxy $group) { $group->post('', function (Request $request, Response $response, array $args): Response { @@ -147,6 +152,9 @@ function extractBearerToken(Request $request): ?string { $future = new DateTime("now +2 hours"); $jti = bin2hex(random_bytes(16)); + if (!isset($PEPPER)) { + throw new HttpError("Pepper is not set"); + } $secret = $PEPPER[0]; $payload = [ diff --git a/src/inc/apiv2/common/AbstractBaseAPI.class.php b/src/inc/apiv2/common/AbstractBaseAPI.class.php index 53ea182be..a7e3ed19a 100644 --- a/src/inc/apiv2/common/AbstractBaseAPI.class.php +++ b/src/inc/apiv2/common/AbstractBaseAPI.class.php @@ -63,8 +63,8 @@ abstract public static function getBaseUri(): string; abstract public function getRequiredPermissions(string $method): array; - /** @var DBA\User|null $user is currently logged in user */ - private User|null $user; + /** @var DBA\User $user is currently logged in user */ + private User $user; /** @var RouteParserInterface|null $routeParser contains routing information * which are for example used dynamic creation of _self references @@ -170,7 +170,7 @@ protected function getUpdateHandlers($id, $current_user): array { * Implementations should use $includedData to collect related resources that should be included * in the API response, such as related entities or additional data. */ - public static function aggregateData(object $object, array &$includedData = [], array $aggregateFieldsets = null): array + public static function aggregateData(object $object, array &$includedData = [], ?array $aggregateFieldsets = null): array { return []; } @@ -294,7 +294,7 @@ protected static function getModelFactory(string $model): object { case User::class: return Factory::getUserFactory(); } - assert(False, "Model '$model' cannot be mapped to Factory"); + throw new HttpError("Model '$model' cannot be mapped to Factory"); } /** @@ -559,7 +559,7 @@ protected static function json2db(array $feature, mixed $obj): ?string { /** * Convert JSON object value to DB insert value, supported by DBA * @throws NotFoundExceptionInterface - * @throws ContainerExceptionInterface, + * @throws ContainerExceptionInterface */ protected function obj2Array(object $obj): array { // Convert values to JSON supported types @@ -588,7 +588,7 @@ protected function obj2Array(object $obj): array { * @throws NotFoundExceptionInterface * @throws ContainerExceptionInterface */ - protected function obj2Resource(object $obj, array &$expandResult = [], array $sparseFieldsets = null, array $aggregateFieldsets = null): array { + protected function obj2Resource(object $obj, array &$expandResult = [], ?array $sparseFieldsets = null, ?array $aggregateFieldsets = null): array { // Convert values to JSON supported types $features = $obj->getFeatures(); $kv = $obj->getKeyValueDict(); @@ -1144,7 +1144,7 @@ protected function makeFilter(array $filters, object $apiClass): array { $qFs[] = new ContainFilter($remappedKey, $valueList, $factory, true); break; default: - assert(False, "Operator '" . $operator . "' not implemented"); + throw new HttpError("Operator '" . $operator . "' not implemented"); } if ($query_operator) { @@ -1174,6 +1174,7 @@ protected function makeOrderFilterTemplates(Request $request, array $features, s foreach ($orderings as $order) { $factory = null; $joinKey = null; + $key = null; $features_sort = $features; if (preg_match('/^(?P[-])?(?P[_a-zA-Z.]+)$/', $order, $matches)) { // Special filtering of _id to use for uniform access to model primary key @@ -1245,8 +1246,8 @@ protected function processExpands( object $object, array $expandResult, array $includedResources, - array $sparseFieldsets = null, - array $aggregateFieldsets = null + ?array $sparseFieldsets = null, + ?array $aggregateFieldsets = null ): array { // Add missing expands to expands in case they have been added in aggregateData() @@ -1347,7 +1348,7 @@ protected function validatePermissions(array $required_perms, array $permsExpand $missingPermissionMatching = true; // if we also have permissions from expanded entries we need to check them as well - if (count($permsExpandMatching) && $this instanceof AbstractModelAPI) { + if (count($permsExpandMatching)) { foreach ($missing_permissions as $missing_permission) { $expands = $permsExpandMatching[$missing_permission]; foreach ($expands as $expand) { @@ -1577,9 +1578,9 @@ protected static function getOneResource(object $apiClass, object $object, Reque $body = $response->getBody(); $body->write($apiClass->ret2json($ret)); - return $response->withStatus($statusCode) - ->withHeader("Content-Type", "application/vnd.api+json") - ->withHeader("Location", $dataResources[0]["links"]["self"]); + return $response->withHeader("Content-Type", "application/vnd.api+json") + ->withHeader("Location", $dataResources[0]["links"]["self"]) + ->withStatus($statusCode); //for location we use links value from $dataresources because if we use $linksSelf, the wrong location gets returned in //case of a POST request } @@ -1589,12 +1590,12 @@ protected static function getOneResource(object $apiClass, object $object, Reque /** * @throws JsonException */ - protected static function getMetaResponse(array $meta, Request $request, Response $response, int $statusCode = 200): MessageInterface|Response { + protected static function getMetaResponse(array $meta, Request $request, Response $response, int $statusCode = 200): Response { $ret = self::createJsonResponse(meta: $meta); $body = $response->getBody(); $body->write(self::ret2json($ret)); - return $response->withStatus($statusCode)->withHeader("Content-Type", "application/vnd.api+json"); + return $response->withHeader("Content-Type", "application/vnd.api+json")->withStatus($statusCode); } /** diff --git a/src/inc/apiv2/common/AbstractHelperAPI.class.php b/src/inc/apiv2/common/AbstractHelperAPI.class.php index 99d9064c6..8ad531479 100644 --- a/src/inc/apiv2/common/AbstractHelperAPI.class.php +++ b/src/inc/apiv2/common/AbstractHelperAPI.class.php @@ -6,6 +6,7 @@ use Psr\Http\Message\MessageInterface; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Slim\App; use Slim\Exception\HttpForbiddenException; abstract class AbstractHelperAPI extends AbstractBaseAPI { @@ -69,14 +70,15 @@ public function processPost(Request $request, Response $response, array $args): } elseif (is_array($newObject)) { return self::getMetaResponse($newObject, $request, $response); + } else { + throw new HttpError("Unable to process request!"); } - throw new HttpError("Unable to process request!"); } /** * Override-able registering of options */ - static public function register($app): void { + static public function register(App $app): void { $me = get_called_class(); $baseUri = $me::getBaseUri(); @@ -131,13 +133,13 @@ protected function handleRangeRequest(int &$start, int &$end, int &$size, &$fp): return false; } if ($range == '-') { - $c_start = $size - substr($range, 1); + $c_start = $size - (int) substr($range, 1); } else { $range = explode('-', $range); - $c_start = $range[0]; + $c_start = (int) $range[0]; if ((isset($range[1]) && is_numeric($range[1]))) { - $c_end = $range[1]; + $c_end = (int) $range[1]; } else { $c_end = $size; diff --git a/src/inc/apiv2/common/AbstractModelAPI.class.php b/src/inc/apiv2/common/AbstractModelAPI.class.php index 0da840ab2..faaec7f4c 100644 --- a/src/inc/apiv2/common/AbstractModelAPI.class.php +++ b/src/inc/apiv2/common/AbstractModelAPI.class.php @@ -6,6 +6,7 @@ use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Slim\App; use DBA\AbstractModelFactory; use DBA\Aggregation; use DBA\JoinFilter; @@ -379,7 +380,7 @@ public function deleteOne(Request $request, Response $response, array $args): Re * @throws ResourceNotFoundError * @throws HttpForbidden */ - protected function doFetch(string $pk, AbstractModelFactory $otherFactory = null): mixed { + protected function doFetch(string $pk, ?AbstractModelFactory $otherFactory = null): mixed { if ($otherFactory != null) { $object = $otherFactory->get($pk); } @@ -545,7 +546,9 @@ protected static function getMinMaxCursor($apiClass, string $sort, array $filter } } $filters[Factory::ORDER] = $orderFilters; - $filters[Factory::JOIN] = $joinFilters; + if (!empty($joinFilters)) { + $filters[Factory::JOIN] = $joinFilters; + } $factory = $apiClass->getFactory(); $result = $factory->filter($filters); //handle joined queries @@ -692,7 +695,7 @@ public static function getManyResources(object $apiClass, Request $request, Resp //pagination filters need to be added after max has been calculated $finalFs[Factory::LIMIT] = new LimitFilter($pageSize); - if (isset($paginationCursor)) { + if (isset($paginationCursor) && isset($operator)) { $decoded_cursor = $apiClass->decode_cursor($paginationCursor); $primary_cursor = $decoded_cursor["primary"]; $primary_cursor_key = key($primary_cursor); @@ -984,14 +987,15 @@ public function getOne(Request $request, Response $response, array $args): Respo * API entry point for modification of single object * @param Request $request * @param Response $response - * @param array $args + * @param mixed $object + * @param mixed $data * @return Response * @throws HTException * @throws HttpError * @throws HttpForbidden * @throws ResourceNotFoundError */ - public function patchSingleObject(Request $request, Response $response, mixed $object, mixed $data) { + public function patchSingleObject(Request $request, Response $response, mixed $object, mixed $data): Response { if (!$this->validateResourceRecord($data)) { return errorResponse($response, "No valid resource identifier object was given as data!", 403); } @@ -1711,6 +1715,7 @@ public function deleteToManyRelationshipLink(Request $request, Response $respons } } else { + $updates = []; foreach ($data as $item) { if (!$this->validateResourceRecord($item)) { $encoded_item = json_encode($item); @@ -1800,7 +1805,7 @@ final public function getPatchValidFeatures(): array { /** * Override-able registering of options */ - static public function register($app): void { + static public function register(App $app): void { $me = get_called_class(); $baseUri = $me::getBaseUri(); $baseUriOne = $baseUri . '/{id:[0-9]+}'; diff --git a/src/inc/apiv2/common/ErrorHandler.class.php b/src/inc/apiv2/common/ErrorHandler.class.php index b25f95e73..f73c7ada1 100644 --- a/src/inc/apiv2/common/ErrorHandler.class.php +++ b/src/inc/apiv2/common/ErrorHandler.class.php @@ -1,11 +1,10 @@ setStatus($status); diff --git a/src/inc/apiv2/common/openAPISchema.routes.php b/src/inc/apiv2/common/openAPISchema.routes.php index 8d7f03970..be678bb25 100644 --- a/src/inc/apiv2/common/openAPISchema.routes.php +++ b/src/inc/apiv2/common/openAPISchema.routes.php @@ -61,7 +61,7 @@ function typeLookup($feature): array { ; -function parsePhpDoc($doc): array|string|null { +function parsePhpDoc($doc): array|string { $cleanedDoc = preg_replace([ '/^\/\*\*/', // Remove opening /** '/\*\/$/', // Remove closing */ @@ -351,6 +351,8 @@ function makeDescription($isRelation, $method, $singleObject): string { return $description; } +use Slim\App; +/** @var App $app */ $app->group("/api/v2/openapi.json", function (RouteCollectorProxy $group) use ($app) { /* Allow CORS preflight requests */ $group->options('', function (Request $request, Response $response): Response { @@ -536,6 +538,9 @@ function makeDescription($isRelation, $method, $singleObject): string { $isToMany = array_key_exists($relation, $class::getToManyRelationships()); $isToOne = array_key_exists($relation, $class::getToOneRelationships()); assert(!($isToMany && $isToOne), "An relationship cant be a to one and to many at the same time."); + } else { + $isToMany = $isToOne = false; + $relation = null; } $expandables = implode(",", $class->getExpandables()); @@ -584,7 +589,7 @@ function makeDescription($isRelation, $method, $singleObject): string { $json_api_header = makeJsonApiHeader(); $links = makeLinks($uri); $properties_return_post_patch = array_merge($json_api_header, $properties_return_post_patch); - $properties_create = buildPatchPost(makeProperties($class->getAllPostParameters($class->getCreateValidFeatures(), true)), $name); + $properties_create = buildPatchPost(makeProperties($class->getAllPostParameters($class->getCreateValidFeatures())), $name); $properties_get = array_merge($json_api_header, $links, $properties_get_single, $included); $properties_patch = buildPatchPost(makeProperties($class->getPatchValidFeatures(), true), $name); $properties_patch_post_relation = buildPostPatchRelation($relation, ($isToMany && !$isToOne)); diff --git a/src/inc/apiv2/helper/abortChunk.routes.php b/src/inc/apiv2/helper/abortChunk.routes.php index d2e006ba0..aff67874b 100644 --- a/src/inc/apiv2/helper/abortChunk.routes.php +++ b/src/inc/apiv2/helper/abortChunk.routes.php @@ -42,4 +42,6 @@ public function actionPost(array $data): object|array|null { } } +use Slim\App; +/** @var App $app */ AbortChunkHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/assignAgent.routes.php b/src/inc/apiv2/helper/assignAgent.routes.php index df227afff..d91add758 100644 --- a/src/inc/apiv2/helper/assignAgent.routes.php +++ b/src/inc/apiv2/helper/assignAgent.routes.php @@ -45,4 +45,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ AssignAgentHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/bulkSupertaskBuilder.routes.php b/src/inc/apiv2/helper/bulkSupertaskBuilder.routes.php index 1fc5e52a8..b07ade2e2 100644 --- a/src/inc/apiv2/helper/bulkSupertaskBuilder.routes.php +++ b/src/inc/apiv2/helper/bulkSupertaskBuilder.routes.php @@ -45,4 +45,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ BulkSupertaskBuilderHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/changeOwnPassword.routes.php b/src/inc/apiv2/helper/changeOwnPassword.routes.php index aae4747e2..60344f654 100644 --- a/src/inc/apiv2/helper/changeOwnPassword.routes.php +++ b/src/inc/apiv2/helper/changeOwnPassword.routes.php @@ -46,4 +46,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ ChangeOwnPasswordHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/createSuperHashlist.routes.php b/src/inc/apiv2/helper/createSuperHashlist.routes.php index 6aedd4b64..20bce869a 100644 --- a/src/inc/apiv2/helper/createSuperHashlist.routes.php +++ b/src/inc/apiv2/helper/createSuperHashlist.routes.php @@ -65,4 +65,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ CreateSuperHashlistHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/createSupertask.routes.php b/src/inc/apiv2/helper/createSupertask.routes.php index 554453073..cc7e681e0 100644 --- a/src/inc/apiv2/helper/createSupertask.routes.php +++ b/src/inc/apiv2/helper/createSupertask.routes.php @@ -71,4 +71,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ CreateSupertaskHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/currentUser.routes.php b/src/inc/apiv2/helper/currentUser.routes.php index 42ca06b44..4cb385728 100644 --- a/src/inc/apiv2/helper/currentUser.routes.php +++ b/src/inc/apiv2/helper/currentUser.routes.php @@ -1,6 +1,5 @@ getKeyspaceProgress(); $keyspace = max($task->getKeyspace(), 1); @@ -222,4 +221,6 @@ static public function register($app): void { } } +use Slim\App; +/** @var App $app */ GetTaskProgressImageHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/getUserPermission.routes.php b/src/inc/apiv2/helper/getUserPermission.routes.php index 6de07efba..04ce44fce 100644 --- a/src/inc/apiv2/helper/getUserPermission.routes.php +++ b/src/inc/apiv2/helper/getUserPermission.routes.php @@ -1,7 +1,6 @@ withHeader("Content-Type", 'application/vnd.api+json;'); } - #[NoReturn] public function actionPost($data): object|array|null { - assert(False, "GetAccessGroups has no POST"); + public function actionPost($data): object|array|null { + throw new HttpError("GetAccessGroups has no POST"); } static public function register($app): void { @@ -70,4 +69,6 @@ public static function getResponse(): array|string|null { } } +use Slim\App; +/** @var App $app */ GetUserPermissionHelperAPI::register($app); diff --git a/src/inc/apiv2/helper/importCrackedHashes.routes.php b/src/inc/apiv2/helper/importCrackedHashes.routes.php index 5c2ca9ee7..c1a4755bc 100644 --- a/src/inc/apiv2/helper/importCrackedHashes.routes.php +++ b/src/inc/apiv2/helper/importCrackedHashes.routes.php @@ -66,4 +66,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ ImportCrackedHashesHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/importFile.routes.php b/src/inc/apiv2/helper/importFile.routes.php index fec46de03..60a746bed 100644 --- a/src/inc/apiv2/helper/importFile.routes.php +++ b/src/inc/apiv2/helper/importFile.routes.php @@ -6,6 +6,7 @@ use Random\RandomException; use Slim\Routing\RouteCollectorProxy; use DBA\Factory; +use Slim\App; /* Default timeout interval for considering an upload stale/incomplete */ const DEFAULT_UPLOAD_EXPIRES_TIMEOUT = 3600; @@ -157,8 +158,8 @@ function processPost(Request $request, Response $response, array $args): Respons $update_metadata = []; $list = explode(",", $update["upload_metadata_raw"]); foreach ($list as $item) { - list($key, $b64val) = explode(" ", $item); - if (!isset($b64val)) { + list($key, $b64val) = explode(" ", $item, 2); + if ($b64val == null) { $response->getBody()->write("Error Upload-Metadata, should be a key value pair that is separated by a space, no value has been provided"); return $response->withStatus(400); } @@ -183,7 +184,7 @@ function processPost(Request $request, Response $response, array $args): Respons else { $id = bin2hex(random_bytes(16)); } - $update["upload_metadata"] = $update_metadata; + $update["upload_metadata"] = $update_metadata ?? null; if ($request->hasHeader('Upload-Defer-Length') && $request->hasHeader('Upload-Length')) { $response->getBody()->write('Error: Cannot provide both Upload-Length and Upload-Defer-Length'); @@ -295,11 +296,11 @@ function processPatch(Request $request, Response $response, array $args): Respon $chunkHash = base64_encode(sha1($chunk, true)); break; case "crc32": - $chunkHash = base64_encode(crc32($chunk, true)); + $chunkHash = base64_encode(crc32($chunk)); break; default: /* Since algorithms are checked in regex, this should never happen */ - assert(False); + throw new HttpError("Hash algorithm not supported"); } if ($chunkHash != $incomingHash) { @@ -367,6 +368,7 @@ function processDelete(Request $request, Response $response, array $args): Respo $filename_meta = self::getMetaPath($args['id']); $uploadExists = file_exists($filename_upload); $metaExists = file_exists($filename_meta); + $isDeletedMeta = $isDeletedUpload = false; if (!$uploadExists && !$metaExists) { throw new HttpError("Upload ID doesnt exists"); } @@ -387,7 +389,7 @@ function processDelete(Request $request, Response $response, array $args): Respo } - static public function register($app): void { + static public function register(App $app): void { $me = get_called_class(); $baseUri = $me::getBaseUri(); @@ -419,4 +421,5 @@ static public function register($app): void { } } +/** @var App $app */ ImportFileHelperAPI::register($app); diff --git a/src/inc/apiv2/helper/maskSupertaskBuilder.routes.php b/src/inc/apiv2/helper/maskSupertaskBuilder.routes.php index 1cd70e651..5e702b4ff 100644 --- a/src/inc/apiv2/helper/maskSupertaskBuilder.routes.php +++ b/src/inc/apiv2/helper/maskSupertaskBuilder.routes.php @@ -44,4 +44,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ MaskSupertaskBuilderHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/purgeTask.routes.php b/src/inc/apiv2/helper/purgeTask.routes.php index 00cc39889..4bba08f1b 100644 --- a/src/inc/apiv2/helper/purgeTask.routes.php +++ b/src/inc/apiv2/helper/purgeTask.routes.php @@ -43,4 +43,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ PurgeTaskHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/rebuildChunkCache.routes.php b/src/inc/apiv2/helper/rebuildChunkCache.routes.php index 224d219b1..dfa3e6d2f 100644 --- a/src/inc/apiv2/helper/rebuildChunkCache.routes.php +++ b/src/inc/apiv2/helper/rebuildChunkCache.routes.php @@ -44,4 +44,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ RebuildChunkCacheHelperAPI::register($app); diff --git a/src/inc/apiv2/helper/recountFileLines.routes.php b/src/inc/apiv2/helper/recountFileLines.routes.php index 80fe8e25c..1427321d6 100644 --- a/src/inc/apiv2/helper/recountFileLines.routes.php +++ b/src/inc/apiv2/helper/recountFileLines.routes.php @@ -50,4 +50,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ RecountFileLinesHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/rescanGlobalFiles.routes.php b/src/inc/apiv2/helper/rescanGlobalFiles.routes.php index fd7f537d1..d24068fec 100644 --- a/src/inc/apiv2/helper/rescanGlobalFiles.routes.php +++ b/src/inc/apiv2/helper/rescanGlobalFiles.routes.php @@ -42,4 +42,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ RescanGlobalFilesHelperAPI::register($app); diff --git a/src/inc/apiv2/helper/resetChunk.routes.php b/src/inc/apiv2/helper/resetChunk.routes.php index 13a6e2eac..373fabc49 100644 --- a/src/inc/apiv2/helper/resetChunk.routes.php +++ b/src/inc/apiv2/helper/resetChunk.routes.php @@ -41,4 +41,6 @@ public function actionPost(array $data): object|array|null { } } +use Slim\App; +/** @var App $app */ ResetChunkHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/resetUserPassword.routes.php b/src/inc/apiv2/helper/resetUserPassword.routes.php index e75bc7488..aa9339eb9 100644 --- a/src/inc/apiv2/helper/resetUserPassword.routes.php +++ b/src/inc/apiv2/helper/resetUserPassword.routes.php @@ -43,4 +43,6 @@ public function actionPost($data): array|null { } } +use Slim\App; +/** @var App $app */ ResetUserPasswordHelperAPI::register($app); diff --git a/src/inc/apiv2/helper/searchHashes.routes.php b/src/inc/apiv2/helper/searchHashes.routes.php index b420c677d..fb32100d6 100644 --- a/src/inc/apiv2/helper/searchHashes.routes.php +++ b/src/inc/apiv2/helper/searchHashes.routes.php @@ -160,7 +160,7 @@ public function actionPost($data): object|array|null { $qF1 = new LikeFilterInsensitive(Hash::PLAINTEXT, "%" . $searchEntry . "%"); $qF2 = new ContainFilter(Hash::HASHLIST_ID, Util::arrayOfIds($userHashlists), Factory::getHashFactory()); $joined2 = Factory::getHashFactory()->filter([Factory::FILTER => [$qF1, $qF2], Factory::JOIN => $jF]); - /** @var $hashes Hash[] */ + /** @var Hash[] $hashes */ $hashes = $joined2[Factory::getHashFactory()->getModelName()]; for ($i = 0; $i < sizeof($hashes); $i++) { $joined[Factory::getHashFactory()->getModelName()][] = $joined2[Factory::getHashFactory()->getModelName()][$i]; @@ -168,7 +168,7 @@ public function actionPost($data): object|array|null { } $resultEntry = []; - /** @var $hashes Hash[] */ + /** @var Hash[] $hashes */ $hashes = $joined[Factory::getHashFactory()->getModelName()]; if (empty($hashes)) { $resultEntry["found"] = false; @@ -179,7 +179,7 @@ public function actionPost($data): object|array|null { $resultEntry["query"] = $searchEntry; $matches = []; for ($i = 0; $i < sizeof($hashes); $i++) { - /** @var $hash Hash */ + /** @var Hash $hash */ $hash = $joined[Factory::getHashFactory()->getModelName()][$i]; $hashlist = $joined[Factory::getHashlistFactory()->getModelName()][$i]; $hashResource = self::obj2Resource($hash); @@ -196,4 +196,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ SearchHashesHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/setUserPassword.routes.php b/src/inc/apiv2/helper/setUserPassword.routes.php index c8faa04a9..80985ce70 100644 --- a/src/inc/apiv2/helper/setUserPassword.routes.php +++ b/src/inc/apiv2/helper/setUserPassword.routes.php @@ -49,4 +49,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ SetUserPasswordHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/helper/taskExtraDetails.routes.php b/src/inc/apiv2/helper/taskExtraDetails.routes.php index b471827fe..a939f606f 100644 --- a/src/inc/apiv2/helper/taskExtraDetails.routes.php +++ b/src/inc/apiv2/helper/taskExtraDetails.routes.php @@ -4,7 +4,6 @@ use DBA\Chunk; use DBA\Factory; use DBA\QueryFilter; -use JetBrains\PhpStorm\NoReturn; use Middlewares\Utils\HttpErrorException; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; @@ -86,8 +85,8 @@ public function handleGet(Request $request, Response $response): Response { return self::getMetaResponse($responseObject, $request, $response); } - #[NoReturn] public function actionPost($data): object|array|null { - assert(false, "TaskExtraDetails has no POST"); + public function actionPost($data): object|array|null { + throw new HttpError("TaskExtraDetails has no POST"); } static public function register($app): void { @@ -108,4 +107,6 @@ public static function getResponse(): array|string|null { } } +use Slim\App; +/** @var App $app */ TaskExtraDetailsHelper::register($app); diff --git a/src/inc/apiv2/helper/unassignAgent.routes.php b/src/inc/apiv2/helper/unassignAgent.routes.php index 48474a27e..56e0ef20e 100644 --- a/src/inc/apiv2/helper/unassignAgent.routes.php +++ b/src/inc/apiv2/helper/unassignAgent.routes.php @@ -42,4 +42,6 @@ public function actionPost($data): object|array|null { } } +use Slim\App; +/** @var App $app */ UnassignAgentHelperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/accessgroups.routes.php b/src/inc/apiv2/model/accessgroups.routes.php index 8b8329cb5..91e6a8bdb 100644 --- a/src/inc/apiv2/model/accessgroups.routes.php +++ b/src/inc/apiv2/model/accessgroups.routes.php @@ -65,4 +65,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ AccessGroupAPI::register($app); diff --git a/src/inc/apiv2/model/agentassignments.routes.php b/src/inc/apiv2/model/agentassignments.routes.php index d3006d6a5..71b11a7c8 100644 --- a/src/inc/apiv2/model/agentassignments.routes.php +++ b/src/inc/apiv2/model/agentassignments.routes.php @@ -98,4 +98,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ AgentAssignmentAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/agentbinaries.routes.php b/src/inc/apiv2/model/agentbinaries.routes.php index d4f852a61..878701584 100644 --- a/src/inc/apiv2/model/agentbinaries.routes.php +++ b/src/inc/apiv2/model/agentbinaries.routes.php @@ -49,4 +49,6 @@ protected function getUpdateHandlers($id, $current_user): array { } } +use Slim\App; +/** @var App $app */ AgentBinaryAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/agenterrors.routes.php b/src/inc/apiv2/model/agenterrors.routes.php index 305c4bcc1..a5380bf9f 100644 --- a/src/inc/apiv2/model/agenterrors.routes.php +++ b/src/inc/apiv2/model/agenterrors.routes.php @@ -9,7 +9,6 @@ use DBA\Factory; use DBA\TaskWrapper; use DBA\User; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -65,12 +64,12 @@ protected function getFilterACL(): array { ]; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "AgentErrors cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("AgentErrors cannot be created via API"); } - #[NoReturn] public function updateObject(int $objectId, array $data): void { - assert(False, "AgentErrors cannot be updated via API"); + public function updateObject(int $objectId, array $data): void { + throw new HttpError("AgentErrors cannot be updated via API"); } protected function deleteObject(object $object): void { @@ -78,4 +77,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ AgentErrorAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/agents.routes.php b/src/inc/apiv2/model/agents.routes.php index d6f76963b..f75dae5a3 100644 --- a/src/inc/apiv2/model/agents.routes.php +++ b/src/inc/apiv2/model/agents.routes.php @@ -14,7 +14,6 @@ use DBA\QueryFilter; use DBA\Task; use DBA\User; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -44,10 +43,10 @@ protected function getUpdateHandlers($id, $current_user): array { * $included_data. * * @param object $object the agent object were data is aggregated from - * @param array &$includedData + * @param array &$included_data * @return array not used here */ - static function aggregateData(object $object, array &$included_data = [], array $aggregateFieldsets = null): array { + static function aggregateData(object $object, array &$included_data = [], ?array $aggregateFieldsets = null): array { $agentId = $object->getId(); $qFs = []; $qFs[] = new QueryFilter(Chunk::AGENT_ID, $agentId, "="); @@ -140,8 +139,8 @@ public static function getToOneRelationships(): array { ]; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "Agents cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("Agents cannot be created via API"); } /** @@ -152,4 +151,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ AgentAPI::register($app); diff --git a/src/inc/apiv2/model/agentstats.routes.php b/src/inc/apiv2/model/agentstats.routes.php index 5e9caac59..1c36196f1 100644 --- a/src/inc/apiv2/model/agentstats.routes.php +++ b/src/inc/apiv2/model/agentstats.routes.php @@ -7,7 +7,6 @@ use DBA\AgentStat; use DBA\JoinFilter; use DBA\User; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -46,12 +45,12 @@ protected function getFilterACL(): array { ]; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "AgentStats cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("AgentStats cannot be created via API"); } - #[NoReturn] public function updateObject(int $objectId, array $data): void { - assert(False, "AgentStats cannot be updated via API"); + public function updateObject(int $objectId, array $data): void { + throw new HttpError("AgentStats cannot be updated via API"); } protected function deleteObject(object $object): void { @@ -59,4 +58,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ AgentStatAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/chunks.routes.php b/src/inc/apiv2/model/chunks.routes.php index a217d76f3..83bd91c93 100644 --- a/src/inc/apiv2/model/chunks.routes.php +++ b/src/inc/apiv2/model/chunks.routes.php @@ -12,7 +12,6 @@ use DBA\Task; use DBA\TaskWrapper; use DBA\User; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -77,17 +76,19 @@ public static function getToOneRelationships(): array { ]; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "Chunks cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("Chunks cannot be created via API"); } - #[NoReturn] public function updateObject(int $objectId, array $data): void { - assert(False, "Chunks cannot be updated via API"); + public function updateObject(int $objectId, array $data): void { + throw new HttpError("Chunks cannot be updated via API"); } - #[NoReturn] protected function deleteObject(object $object): void { - assert(False, "Chunks cannot be deleted via API"); + protected function deleteObject(object $object): void { + throw new HttpError("Chunks cannot be deleted via API"); } } +use Slim\App; +/** @var App $app */ ChunkAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/configs.routes.php b/src/inc/apiv2/model/configs.routes.php index bbab7f121..c4ddf3461 100644 --- a/src/inc/apiv2/model/configs.routes.php +++ b/src/inc/apiv2/model/configs.routes.php @@ -2,7 +2,6 @@ use DBA\Config; use DBA\ConfigSection; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -31,12 +30,12 @@ public static function getToOneRelationships(): array { ]; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "Configs cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("Configs cannot be created via API"); } - #[NoReturn] protected function deleteObject(object $object): void { - assert(False, "Configs cannot be deleted via API"); + protected function deleteObject(object $object): void { + throw new HttpError("Configs cannot be deleted via API"); } /** @@ -47,4 +46,6 @@ protected function updateObjects(array $objects): void { } } +use Slim\App; +/** @var App $app */ ConfigAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/configsections.routes.php b/src/inc/apiv2/model/configsections.routes.php index 60b0bfc96..133729c9b 100644 --- a/src/inc/apiv2/model/configsections.routes.php +++ b/src/inc/apiv2/model/configsections.routes.php @@ -1,7 +1,6 @@ fn($value) => HashListUtils::setArchived($id, $value, $current_user), - Hashlist::NOTES => fn($value) => HashListUtils::editNotes($id, $value, $current_user), - Hashlist::IS_SECRET => fn($value) => HashListUtils::setSecret($id, $value, $current_user), - Hashlist::HASHLIST_NAME => fn($value) => HashListUtils::rename($id, $value, $current_user), - Hashlist::ACCESS_GROUP_ID => fn($value) => HashListUtils::changeAccessGroup($id, $value, $current_user) + Hashlist::IS_ARCHIVED => fn($value) => HashlistUtils::setArchived($id, $value, $current_user), + Hashlist::NOTES => fn($value) => HashlistUtils::editNotes($id, $value, $current_user), + Hashlist::IS_SECRET => fn($value) => HashlistUtils::setSecret($id, $value, $current_user), + Hashlist::HASHLIST_NAME => fn($value) => HashlistUtils::rename($id, $value, $current_user), + Hashlist::ACCESS_GROUP_ID => fn($value) => HashlistUtils::changeAccessGroup($id, $value, $current_user) ]; } } +use Slim\App; +/** @var App $app */ HashlistAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/hashtypes.routes.php b/src/inc/apiv2/model/hashtypes.routes.php index c83d94c6d..8cd48512e 100644 --- a/src/inc/apiv2/model/hashtypes.routes.php +++ b/src/inc/apiv2/model/hashtypes.routes.php @@ -37,4 +37,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ HashTypeAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/healthcheckagents.routes.php b/src/inc/apiv2/model/healthcheckagents.routes.php index eea339fac..5c9832716 100644 --- a/src/inc/apiv2/model/healthcheckagents.routes.php +++ b/src/inc/apiv2/model/healthcheckagents.routes.php @@ -65,18 +65,20 @@ public static function getToOneRelationships(): array { ]; } - #[NoReturn] protected function createObject(array $object): int { - assert(False, "HealthCheckAgents cannot be created via API"); + protected function createObject(array $object): int { + throw new HttpError("HealthCheckAgents cannot be created via API"); } - #[NoReturn] public function updateObject(int $objectId, array $data): void { - assert(False, "HealthCheckAgents cannot be updated via API"); + public function updateObject(int $objectId, array $data): void { + throw new HttpError("HealthCheckAgents cannot be updated via API"); } - #[NoReturn] protected function deleteObject(object $object): void { + protected function deleteObject(object $object): void { /* Dummy code to implement abstract functions */ - assert(False, "HealthCheckAgents cannot be deleted via API"); + throw new HttpError("HealthCheckAgents cannot be deleted via API"); } } +use Slim\App; +/** @var App $app */ HealthCheckAgentAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/healthchecks.routes.php b/src/inc/apiv2/model/healthchecks.routes.php index 2a49e1f6f..3d4a71289 100644 --- a/src/inc/apiv2/model/healthchecks.routes.php +++ b/src/inc/apiv2/model/healthchecks.routes.php @@ -67,4 +67,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ HealthCheckAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/logentries.routes.php b/src/inc/apiv2/model/logentries.routes.php index a05241fbd..97795b542 100644 --- a/src/inc/apiv2/model/logentries.routes.php +++ b/src/inc/apiv2/model/logentries.routes.php @@ -3,7 +3,6 @@ use DBA\Factory; use DBA\LogEntry; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -17,13 +16,15 @@ public static function getDBAclass(): string { return LogEntry::class; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "Logentries cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("Logentries cannot be created via API"); } protected function deleteObject(object $object): void { - assert(False, "Logentries cannot be deleted via API"); + throw new HttpError("Logentries cannot be deleted via API"); } } +use Slim\App; +/** @var App $app */ LogEntryAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/notifications.routes.php b/src/inc/apiv2/model/notifications.routes.php index 2bea8d61b..caba4dea2 100644 --- a/src/inc/apiv2/model/notifications.routes.php +++ b/src/inc/apiv2/model/notifications.routes.php @@ -84,4 +84,6 @@ protected function getUpdateHandlers($id, $current_user): array { } } +use Slim\App; +/** @var App $app */ NotificationSettingAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/preprocessors.routes.php b/src/inc/apiv2/model/preprocessors.routes.php index 49e8ffc40..367fd5ed6 100644 --- a/src/inc/apiv2/model/preprocessors.routes.php +++ b/src/inc/apiv2/model/preprocessors.routes.php @@ -52,4 +52,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ PreprocessorAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/pretasks.routes.php b/src/inc/apiv2/model/pretasks.routes.php index c542f4196..5082ce9ab 100644 --- a/src/inc/apiv2/model/pretasks.routes.php +++ b/src/inc/apiv2/model/pretasks.routes.php @@ -65,9 +65,9 @@ protected function createObject(array $data): int { } //TODO make aggregate data queryable and not included by default - static function aggregateData(object $object, array &$included_data = [], array $aggregateFieldsets = null): array { + static function aggregateData(object $object, array &$included_data = [], ?array $aggregateFieldsets = null): array { $aggregatedData = []; - if (is_null($aggregateFieldsets) || (is_array($aggregateFieldsets) && array_key_exists('pretask', $aggregateFieldsets))) { + if (is_null($aggregateFieldsets) || array_key_exists('pretask', $aggregateFieldsets)) { $qF1 = new QueryFilter(FilePretask::PRETASK_ID, $object->getId(), "=", Factory::getFilePretaskFactory()); $jF1 = new JoinFilter(Factory::getFilePretaskFactory(), File::FILE_ID, FilePretask::FILE_ID); @@ -104,4 +104,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ PreTaskAPI::register($app); diff --git a/src/inc/apiv2/model/speeds.routes.php b/src/inc/apiv2/model/speeds.routes.php index 98d9e448f..a84cab475 100644 --- a/src/inc/apiv2/model/speeds.routes.php +++ b/src/inc/apiv2/model/speeds.routes.php @@ -11,7 +11,6 @@ use DBA\Task; use DBA\TaskWrapper; use DBA\User; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -88,17 +87,19 @@ public static function getToOneRelationships(): array { ]; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "Speeds cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("Speeds cannot be created via API"); } - #[NoReturn] public function updateObject(int $objectId, array $data): void { - assert(False, "Speeds cannot be updated via API"); + public function updateObject(int $objectId, array $data): void { + throw new HttpError("Speeds cannot be updated via API"); } - #[NoReturn] protected function deleteObject(object $object): void { - assert(False, "Speeds cannot be deleted via API"); + protected function deleteObject(object $object): void { + throw new HttpError("Speeds cannot be deleted via API"); } } +use Slim\App; +/** @var App $app */ SpeedAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/supertasks.routes.php b/src/inc/apiv2/model/supertasks.routes.php index 0488c67f1..7165a1035 100644 --- a/src/inc/apiv2/model/supertasks.routes.php +++ b/src/inc/apiv2/model/supertasks.routes.php @@ -72,12 +72,12 @@ public function updateToManyRelationship(Request $request, array $data, array $a // Find out which to add and remove $currentPretasks = SupertaskUtils::getPretasksOfSupertask($id); - function compare_ids($a, $b) { + $compare_ids = static function($a, $b) { return ($a->getId() - $b->getId()); - } + }; - $toAddPretasks = array_udiff($wantedPretasks, $currentPretasks, 'compare_ids'); - $toRemovePretasks = array_udiff($currentPretasks, $wantedPretasks, 'compare_ids'); + $toAddPretasks = array_udiff($wantedPretasks, $currentPretasks, $compare_ids); + $toRemovePretasks = array_udiff($currentPretasks, $wantedPretasks, $compare_ids); $factory = $this->getFactory(); $factory->getDB()->beginTransaction(); //start transaction to be able roll back @@ -103,4 +103,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ SupertaskAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/tasks.routes.php b/src/inc/apiv2/model/tasks.routes.php index 7f3b8bee5..c2ed6bb35 100644 --- a/src/inc/apiv2/model/tasks.routes.php +++ b/src/inc/apiv2/model/tasks.routes.php @@ -162,10 +162,10 @@ protected function createObject(array $data): int { } //TODO make aggregate data queryable and not included by default - static function aggregateData(object $object, array &$included_data = [], array $aggregateFieldsets = null): array { + static function aggregateData(object $object, array &$included_data = [], ?array $aggregateFieldsets = null): array { $aggregatedData = []; - if (is_null($aggregateFieldsets) || (is_array($aggregateFieldsets) && array_key_exists('task', $aggregateFieldsets))) { + if (is_null($aggregateFieldsets) || array_key_exists('task', $aggregateFieldsets)) { if (!is_null($aggregateFieldsets)) { $aggregateFieldsets['task'] = explode(",", $aggregateFieldsets['task']); } @@ -232,4 +232,6 @@ protected function getUpdateHandlers($id, $current_user): array { } } +use Slim\App; +/** @var App $app */ TaskAPI::register($app); diff --git a/src/inc/apiv2/model/taskwrappers.routes.php b/src/inc/apiv2/model/taskwrappers.routes.php index d333d0083..b3f6851ba 100644 --- a/src/inc/apiv2/model/taskwrappers.routes.php +++ b/src/inc/apiv2/model/taskwrappers.routes.php @@ -13,7 +13,6 @@ use DBA\Task; use DBA\TaskWrapper; use DBA\User; -use JetBrains\PhpStorm\NoReturn; require_once(dirname(__FILE__) . "/../common/AbstractModelAPI.class.php"); @@ -137,8 +136,8 @@ protected function parseFilters(array $filters) { return $filters; } - #[NoReturn] protected function createObject(array $data): int { - assert(False, "TaskWrappers cannot be created via API"); + protected function createObject(array $data): int { + throw new HttpError("TaskWrappers cannot be created via API"); } protected function getUpdateHandlers($id, $current_user): array { @@ -170,9 +169,11 @@ protected function deleteObject(object $object): void { TaskUtils::deleteSupertask($object->getId(), $this->getCurrentUser()); break; default: - assert(False, "Internal Error: taskType not recognized"); + throw new HttpError("Internal Error: taskType not recognized"); } } } +use Slim\App; +/** @var App $app */ TaskWrapperAPI::register($app); \ No newline at end of file diff --git a/src/inc/apiv2/model/users.routes.php b/src/inc/apiv2/model/users.routes.php index 917937ca1..4db19b101 100644 --- a/src/inc/apiv2/model/users.routes.php +++ b/src/inc/apiv2/model/users.routes.php @@ -128,4 +128,6 @@ protected function getUpdateHandlers($id, $current_user): array { } +use Slim\App; +/** @var App $app */ UserAPI::register($app); diff --git a/src/inc/apiv2/model/vouchers.routes.php b/src/inc/apiv2/model/vouchers.routes.php index 88c348a9f..fbaf79342 100644 --- a/src/inc/apiv2/model/vouchers.routes.php +++ b/src/inc/apiv2/model/vouchers.routes.php @@ -34,4 +34,6 @@ protected function deleteObject(object $object): void { } } +use Slim\App; +/** @var App $app */ VoucherAPI::register($app); \ No newline at end of file