diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2022-07-14 14:30:08 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-14 14:30:08 +0300 |
commit | cabb922fdef6a6907242ceaf4d723d4dc54d9681 (patch) | |
tree | c6ffba849d133a08424136cf9972a50f73f11ef8 | |
parent | 8e9a634009dbf071afaa3973755bc78ad34a1f45 (diff) | |
parent | 9b8c5d2037ce4fdb2c0c5f8aeed3ac2a9e33b257 (diff) |
[stable24] get rid of mspt
123 files changed, 8143 insertions, 1555 deletions
diff --git a/appinfo/info.xml b/appinfo/info.xml index 7550b5c..5815e4b 100755 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -38,10 +38,6 @@ </background-jobs> <commands> - <command>OCA\Backup\Command\RemoteAdd</command> - <command>OCA\Backup\Command\RemoteList</command> - <command>OCA\Backup\Command\RemoteRemove</command> - <command>OCA\Backup\Command\ExternalAdd</command> <command>OCA\Backup\Command\ExternalAppData</command> <command>OCA\Backup\Command\ExternalList</command> diff --git a/appinfo/routes.php b/appinfo/routes.php index 3ca5a11..ba7e4e0 100755 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -1,7 +1,6 @@ <?php return [ - 'ocs' => [ ['name' => 'Local#setupExport', 'url' => '/setup/{encrypted}', 'verb' => 'GET'], ['name' => 'Local#getSettings', 'url' => '/settings', 'verb' => 'GET'], @@ -14,22 +13,5 @@ return [ ['name' => 'Local#unsetExternalFolder', 'url' => '/external/{storageId}', 'verb' => 'DELETE'], ['name' => 'Local#initAction', 'url' => '/action/{type}/{param}', 'verb' => 'POST'] - ], - - 'routes' => [ - ['name' => 'Remote#appService', 'url' => '/', 'verb' => 'GET'], - ['name' => 'Remote#test', 'url' => '/test', 'verb' => 'GET'], - - ['name' => 'Remote#listRestoringPoint', 'url' => '/rp', 'verb' => 'GET'], - ['name' => 'Remote#getRestoringPoint', 'url' => '/rp/{pointId}', 'verb' => 'GET'], - ['name' => 'Remote#healthRestoringPoint', 'url' => '/rp/{pointId}/health', 'verb' => 'GET'], - [ - 'name' => 'Remote#downloadRestoringPoint', 'url' => '/rp/{pointId}/{chunkName}download', - 'verb' => 'GET' - ], - ['name' => 'Remote#createRestoringPoint', 'url' => '/rp', 'verb' => 'PUT'], - ['name' => 'Remote#updateRestoringPoint', 'url' => '/rp/{pointId}', 'verb' => 'POST'], - ['name' => 'Remote#deleteRestoringPoint', 'url' => '/rp/{pointId}', 'verb' => 'DELETE'], - ['name' => 'Remote#uploadRestoringChunk', 'url' => '/rp/{pointId}/{chunkName}', 'verb' => 'POST'] ] ]; diff --git a/composer.json b/composer.json index db32a93..0dfc3b6 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,6 @@ } }, "require": { - "artificial-owl/my-small-php-tools": "~23", "ifsnop/mysqldump-php": "2.9", "spatie/db-dumper": "2.21.1", "pimple/pimple": "~3.0" diff --git a/composer.lock b/composer.lock index 584e4b7..2e87e0e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,49 +4,9 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "58f410e2909d6c111cebb70fbf169dad", + "content-hash": "e60ad1f6aebc7b99bda0bf749e5a91b2", "packages": [ { - "name": "artificial-owl/my-small-php-tools", - "version": "v23.0.11", - "source": { - "type": "git", - "url": "https://github.com/ArtificialOwl/my-small-php-tools.git", - "reference": "45b29e1c90d47ff3e89338135243d78e82dc7b6c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ArtificialOwl/my-small-php-tools/zipball/45b29e1c90d47ff3e89338135243d78e82dc7b6c", - "reference": "45b29e1c90d47ff3e89338135243d78e82dc7b6c", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "ArtificialOwl\\MySmallPhpTools\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "AGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Maxence Lange", - "email": "maxence@artificial-owl.com" - } - ], - "description": "My small PHP Tools", - "support": { - "issues": "https://github.com/ArtificialOwl/my-small-php-tools/issues", - "source": "https://github.com/ArtificialOwl/my-small-php-tools/tree/v23.0.11" - }, - "time": "2021-11-17T20:25:01+00:00" - }, - { "name": "ifsnop/mysqldump-php", "version": "v2.9", "source": { @@ -273,16 +233,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -291,7 +251,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -336,7 +296,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" }, "funding": [ { @@ -352,20 +312,20 @@ "type": "tidelift" } ], - "time": "2022-03-04T08:16:47+00:00" + "time": "2022-05-10T07:21:04+00:00" }, { "name": "symfony/process", - "version": "v5.4.5", + "version": "v5.4.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "95440409896f90a5f85db07a32b517ecec17fa4c" + "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/95440409896f90a5f85db07a32b517ecec17fa4c", - "reference": "95440409896f90a5f85db07a32b517ecec17fa4c", + "url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3", + "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3", "shasum": "" }, "require": { @@ -398,7 +358,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.5" + "source": "https://github.com/symfony/process/tree/v5.4.8" }, "funding": [ { @@ -414,7 +374,7 @@ "type": "tidelift" } ], - "time": "2022-01-30T18:16:22+00:00" + "time": "2022-04-08T05:07:18+00:00" } ], "packages-dev": [ @@ -491,16 +451,16 @@ }, { "name": "composer/semver", - "version": "3.3.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "5d8e574bb0e69188786b8ef77d43341222a41a71" + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/5d8e574bb0e69188786b8ef77d43341222a41a71", - "reference": "5d8e574bb0e69188786b8ef77d43341222a41a71", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", "shasum": "" }, "require": { @@ -552,7 +512,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.1" + "source": "https://github.com/composer/semver/tree/3.3.2" }, "funding": [ { @@ -568,7 +528,7 @@ "type": "tidelift" } ], - "time": "2022-03-16T11:22:07+00:00" + "time": "2022-04-01T19:23:25+00:00" }, { "name": "composer/xdebug-handler", @@ -638,16 +598,16 @@ }, { "name": "doctrine/annotations", - "version": "1.13.2", + "version": "1.13.3", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08" + "reference": "648b0343343565c4a056bfc8392201385e8d89f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0", "shasum": "" }, "require": { @@ -659,9 +619,10 @@ "require-dev": { "doctrine/cache": "^1.11 || ^2.0", "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^0.12.20", + "phpstan/phpstan": "^1.4.10 || ^1.8.0", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2" + "symfony/cache": "^4.4 || ^5.2", + "vimeo/psalm": "^4.10" }, "type": "library", "autoload": { @@ -704,9 +665,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.2" + "source": "https://github.com/doctrine/annotations/tree/1.13.3" }, - "time": "2021-08-05T19:00:23+00:00" + "time": "2022-07-02T10:48:51+00:00" }, { "name": "doctrine/instantiator", @@ -856,16 +817,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.8.0", + "version": "v3.9.3", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3" + "reference": "bad87e63d7d87efa5e82aa4feafa52df6a37e6c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", - "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/bad87e63d7d87efa5e82aa4feafa52df6a37e6c1", + "reference": "bad87e63d7d87efa5e82aa4feafa52df6a37e6c1", "shasum": "" }, "require": { @@ -933,7 +894,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.8.0" + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.9.3" }, "funding": [ { @@ -941,7 +902,7 @@ "type": "github" } ], - "time": "2022-03-18T17:20:59+00:00" + "time": "2022-07-13T09:53:20+00:00" }, { "name": "myclabs/deep-copy", @@ -3025,16 +2986,16 @@ }, { "name": "symfony/console", - "version": "v5.4.5", + "version": "v5.4.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad" + "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d8111acc99876953f52fe16d4c50eb60940d49ad", - "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad", + "url": "https://api.github.com/repos/symfony/console/zipball/4d671ab4ddac94ee439ea73649c69d9d200b5000", + "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000", "shasum": "" }, "require": { @@ -3104,7 +3065,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.5" + "source": "https://github.com/symfony/console/tree/v5.4.10" }, "funding": [ { @@ -3120,20 +3081,20 @@ "type": "tidelift" } ], - "time": "2022-02-24T12:45:35+00:00" + "time": "2022-06-26T13:00:04+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", "shasum": "" }, "require": { @@ -3171,7 +3132,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" }, "funding": [ { @@ -3187,20 +3148,20 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.3", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d" + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dec8a9f58d20df252b9cd89f1c6c1530f747685d", - "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", "shasum": "" }, "require": { @@ -3256,7 +3217,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" }, "funding": [ { @@ -3272,20 +3233,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-05-05T16:45:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1", "shasum": "" }, "require": { @@ -3335,7 +3296,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.2" }, "funding": [ { @@ -3351,20 +3312,20 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.6", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "d53a45039974952af7f7ebc461ccdd4295e29440" + "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/d53a45039974952af7f7ebc461ccdd4295e29440", - "reference": "d53a45039974952af7f7ebc461ccdd4295e29440", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/36a017fa4cce1eff1b8e8129ff53513abcef05ba", + "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba", "shasum": "" }, "require": { @@ -3399,7 +3360,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.6" + "source": "https://github.com/symfony/filesystem/tree/v5.4.9" }, "funding": [ { @@ -3415,20 +3376,20 @@ "type": "tidelift" } ], - "time": "2022-03-02T12:42:23+00:00" + "time": "2022-05-20T13:55:35+00:00" }, { "name": "symfony/finder", - "version": "v5.4.3", + "version": "v5.4.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d" + "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/231313534dded84c7ecaa79d14bc5da4ccb69b7d", - "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d", + "url": "https://api.github.com/repos/symfony/finder/zipball/9b630f3427f3ebe7cd346c277a1408b00249dad9", + "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9", "shasum": "" }, "require": { @@ -3462,7 +3423,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.3" + "source": "https://github.com/symfony/finder/tree/v5.4.8" }, "funding": [ { @@ -3478,7 +3439,7 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:34:36+00:00" + "time": "2022-04-15T08:07:45+00:00" }, { "name": "symfony/options-resolver", @@ -3633,16 +3594,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "433d05519ce6990bf3530fba6957499d327395c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", "shasum": "" }, "require": { @@ -3654,7 +3615,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3694,7 +3655,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" }, "funding": [ { @@ -3710,20 +3671,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", "shasum": "" }, "require": { @@ -3735,7 +3696,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3778,7 +3739,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" }, "funding": [ { @@ -3794,20 +3755,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { @@ -3822,7 +3783,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3861,7 +3822,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" }, "funding": [ { @@ -3877,20 +3838,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", "shasum": "" }, "require": { @@ -3899,7 +3860,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3940,7 +3901,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" }, "funding": [ { @@ -3956,20 +3917,20 @@ "type": "tidelift" } ], - "time": "2021-06-05T21:20:04+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", "shasum": "" }, "require": { @@ -3978,7 +3939,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4019,7 +3980,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" }, "funding": [ { @@ -4035,7 +3996,7 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:11+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/service-contracts", @@ -4162,16 +4123,16 @@ }, { "name": "symfony/string", - "version": "v5.4.3", + "version": "v5.4.10", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10" + "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10", + "url": "https://api.github.com/repos/symfony/string/zipball/4432bc7df82a554b3e413a8570ce2fea90e94097", + "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097", "shasum": "" }, "require": { @@ -4228,7 +4189,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.3" + "source": "https://github.com/symfony/string/tree/v5.4.10" }, "funding": [ { @@ -4244,7 +4205,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-06-26T15:57:47+00:00" }, { "name": "theseer/tokenizer", diff --git a/lib/Activity/Provider.php b/lib/Activity/Provider.php index be0673d..3ccf462 100644 --- a/lib/Activity/Provider.php +++ b/lib/Activity/Provider.php @@ -31,17 +31,17 @@ declare(strict_types=1); namespace OCA\Backup\Activity; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use Exception; use InvalidArgumentException; use OCA\Backup\AppInfo\Application; use OCA\Backup\Service\ActivityService; +use OCA\Backup\Tools\Traits\TArrayTools; use OCP\Activity\IEvent; use OCP\Activity\IManager; use OCP\Activity\IProvider; use OCP\IL10N; use OCP\IURLGenerator; +use OCA\Backup\Tools\Traits\TStringTools; /** * Class Provider diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 0b28e69..1ecda50 100755 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -76,7 +76,7 @@ class Application extends App implements IBootstrap { $context->registerEventListener(NodeWrittenEvent::class, NodeEvent::class); $context->registerEventListener(NodeRenamedEvent::class, NodeEvent::class); - $context->registerWellKnownHandler(WebfingerHandler::class); +// $context->registerWellKnownHandler(WebfingerHandler::class); $context->registerEventListener(LoadAdditionalScriptsEvent::class, FilesAdditionalScripts::class); } diff --git a/lib/Command/ExternalAppData.php b/lib/Command/ExternalAppData.php index 8f8bb6a..dd2de22 100755 --- a/lib/Command/ExternalAppData.php +++ b/lib/Command/ExternalAppData.php @@ -31,13 +31,13 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; use OC\Core\Command\Base; use OCA\Backup\Exceptions\ExternalAppdataException; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; use OCA\Backup\Service\ConfigService; use OCA\Backup\Service\ExternalFolderService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Traits\TDeserialize; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCP\Files\StorageNotAvailableException; use Symfony\Component\Console\Input\InputInterface; @@ -53,7 +53,7 @@ use Symfony\Component\Console\Question\Question; * @package OCA\Backup\Command */ class ExternalAppData extends Base { - use TNC23Deserialize; + use TDeserialize; /** @var PointService */ diff --git a/lib/Command/FileSearch.php b/lib/Command/FileSearch.php index 9fe136d..bdc5cf8 100755 --- a/lib/Command/FileSearch.php +++ b/lib/Command/FileSearch.php @@ -31,9 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use OC\Core\Command\Base; use OCA\Backup\Exceptions\ArchiveCreateException; use OCA\Backup\Exceptions\ArchiveNotFoundException; @@ -45,8 +42,11 @@ use OCA\Backup\Model\RestoringData; use OCA\Backup\Model\RestoringPoint; use OCA\Backup\Service\ChunkService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCA\Backup\Tools\Traits\TStringTools; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -61,7 +61,7 @@ use Symfony\Component\Console\Output\OutputInterface; class FileSearch extends Base { use TArrayTools; use TStringTools; - use TNC23Deserialize; + use TDeserialize; /** @var PointService */ @@ -95,7 +95,7 @@ class FileSearch extends Base { ->setDescription('Search a specific file in your restoring points') ->addArgument('search', InputArgument::REQUIRED, 'path/name to search') ->addOption( - 'point', '', InputOption::VALUE_REQUIRED, 'Id of a restoring point for targeted search' + 'point', '', InputOption::VALUE_REQUIRED, 'Id of a restoring point for targeted search' ) ->addOption('since', '', InputOption::VALUE_REQUIRED, 'search in a specific timeline') ->addOption('until', '', InputOption::VALUE_REQUIRED, 'search in a specific timeline'); diff --git a/lib/Command/PointArchive.php b/lib/Command/PointArchive.php index 954a16c..0f2a7d5 100755 --- a/lib/Command/PointArchive.php +++ b/lib/Command/PointArchive.php @@ -31,7 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; use OC\Core\Command\Base; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; use OCA\Backup\Exceptions\MetadataException; @@ -44,6 +43,7 @@ use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Exceptions\RestoringPointPackException; use OCA\Backup\Service\OccService; use OCA\Backup\Service\OutputService; +use OCA\Backup\Tools\Exceptions\SignatoryException; use OCP\Files\GenericFileException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; diff --git a/lib/Command/PointComment.php b/lib/Command/PointComment.php index 15507ff..0eb0dc6 100755 --- a/lib/Command/PointComment.php +++ b/lib/Command/PointComment.php @@ -31,7 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; use OC\Core\Command\Base; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; use OCA\Backup\Exceptions\MetadataException; @@ -44,6 +43,7 @@ use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Exceptions\RestoringPointPackException; use OCA\Backup\Service\OccService; use OCA\Backup\Service\OutputService; +use OCA\Backup\Tools\Exceptions\SignatoryException; use OCP\Files\GenericFileException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; diff --git a/lib/Command/PointCreate.php b/lib/Command/PointCreate.php index e37c4d7..23bf686 100755 --- a/lib/Command/PointCreate.php +++ b/lib/Command/PointCreate.php @@ -88,7 +88,7 @@ class PointCreate extends Base { ->addArgument('comment', InputArgument::OPTIONAL, 'set a comment to the restoring point', '') ->addOption('generate-log', '', InputOption::VALUE_NONE, 'generate a log file') ->addOption( - 'differential', '', InputOption::VALUE_NONE, 'create an differential restoring point' + 'differential', '', InputOption::VALUE_NONE, 'create an differential restoring point' ); } diff --git a/lib/Command/PointDelete.php b/lib/Command/PointDelete.php index 9628fe3..cd036ed 100755 --- a/lib/Command/PointDelete.php +++ b/lib/Command/PointDelete.php @@ -98,15 +98,15 @@ class PointDelete extends Base { ->setDescription('Locally delete a restoring point') ->addArgument('pointId', InputArgument::REQUIRED, 'id of the restoring point to delete') ->addOption( - 'all-storages', '', InputOption::VALUE_NONE, 'remove restoring point from all storage' + 'all-storages', '', InputOption::VALUE_NONE, 'remove restoring point from all storage' ) ->addOption( - 'remote', '', InputOption::VALUE_REQUIRED, - 'remove a restoring point from a remote instance (or local)', '' + 'remote', '', InputOption::VALUE_REQUIRED, + 'remove a restoring point from a remote instance (or local)', '' ) ->addOption( - 'external', '', InputOption::VALUE_REQUIRED, - 'remove a restoring point from an external folder', '' + 'external', '', InputOption::VALUE_REQUIRED, + 'remove a restoring point from an external folder', '' ); } diff --git a/lib/Command/PointDetails.php b/lib/Command/PointDetails.php index 284cb65..5908b08 100755 --- a/lib/Command/PointDetails.php +++ b/lib/Command/PointDetails.php @@ -31,8 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use OC\Core\Command\Base; use OCA\Backup\Exceptions\ArchiveNotFoundException; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; @@ -53,9 +51,11 @@ use OCA\Backup\Service\ExternalFolderService; use OCA\Backup\Service\PackService; use OCA\Backup\Service\PointService; use OCA\Backup\Service\RemoteService; +use OCA\Backup\Tools\Traits\TArrayTools; use OCP\Files\GenericFileException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCA\Backup\Tools\Traits\TStringTools; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; diff --git a/lib/Command/PointDownload.php b/lib/Command/PointDownload.php index 267de5d..5c014fc 100755 --- a/lib/Command/PointDownload.php +++ b/lib/Command/PointDownload.php @@ -31,8 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; use OC\Core\Command\Base; use OCA\Backup\Db\PointRequest; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; @@ -56,6 +54,8 @@ use OCA\Backup\Service\PackService; use OCA\Backup\Service\PointService; use OCA\Backup\Service\RemoteService; use OCA\Backup\Service\RemoteStreamService; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Exceptions\SignatureException; use OCP\Files\GenericFileException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -100,7 +100,7 @@ class PointDownload extends Base { /** @var ConfigService */ private $configService; - + /** @var MetadataService */ private $metadataService; @@ -156,7 +156,7 @@ class PointDownload extends Base { ->addOption('remote', '', InputOption::VALUE_REQUIRED, 'address of the remote instance') ->addOption('external', '', InputOption::VALUE_REQUIRED, 'storageId of the external storage') ->addOption( - 'no-check', '', InputOption::VALUE_NONE, 'do not check integrity of restoring point' + 'no-check', '', InputOption::VALUE_NONE, 'do not check integrity of restoring point' ); } diff --git a/lib/Command/PointHistory.php b/lib/Command/PointHistory.php index 6445853..9b7fca9 100755 --- a/lib/Command/PointHistory.php +++ b/lib/Command/PointHistory.php @@ -31,10 +31,10 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OC\Core\Command\Base; use OCA\Backup\Service\ChunkService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Traits\TNCLogger; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -44,7 +44,7 @@ use Symfony\Component\Console\Output\OutputInterface; * @package OCA\Backup\Command */ class PointHistory extends Base { - use TNC23Logger; + use TNCLogger; /** @var PointService */ diff --git a/lib/Command/PointList.php b/lib/Command/PointList.php index 2182716..310c8bb 100755 --- a/lib/Command/PointList.php +++ b/lib/Command/PointList.php @@ -31,9 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use OC\Core\Command\Base; use OCA\Backup\Model\RemoteInstance; use OCA\Backup\Model\RestoringData; @@ -42,6 +39,9 @@ use OCA\Backup\Model\RestoringPoint; use OCA\Backup\Service\OutputService; use OCA\Backup\Service\PointService; use OCA\Backup\Service\RemoteStreamService; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Exceptions\SignatureException; +use OCA\Backup\Tools\Traits\TStringTools; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -94,16 +94,16 @@ class PointList extends Base { $this->setName('backup:point:list') ->setDescription('List restoring point') ->addOption( - 'local', '', InputOption::VALUE_NONE, - 'list restoring point from local only' + 'local', '', InputOption::VALUE_NONE, + 'list restoring point from local only' ) ->addOption( - 'remote', '', InputOption::VALUE_REQUIRED, - 'list restoring point from a remote instance (or local)', '' + 'remote', '', InputOption::VALUE_REQUIRED, + 'list restoring point from a remote instance (or local)', '' ) ->addOption( - 'external', '', InputOption::VALUE_REQUIRED, - 'list restoring point from an external folder', '' + 'external', '', InputOption::VALUE_REQUIRED, + 'list restoring point from an external folder', '' ); } diff --git a/lib/Command/PointRestore.php b/lib/Command/PointRestore.php index 440d628..7afe916 100755 --- a/lib/Command/PointRestore.php +++ b/lib/Command/PointRestore.php @@ -31,9 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use Exception; use OC\Core\Command\Base; use OCA\Backup\Exceptions\ArchiveCreateException; @@ -60,8 +57,11 @@ use OCA\Backup\Service\FilesService; use OCA\Backup\Service\OutputService; use OCA\Backup\Service\PointService; use OCA\Backup\Service\RestoreService; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Traits\TArrayTools; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCA\Backup\Tools\Traits\TStringTools; use Symfony\Component\Console\Exception\InvalidOptionException; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputArgument; @@ -339,13 +339,13 @@ class PointRestore extends Base { $this->chunkService->restoreChunk($point, $chunk, $root); $this->output->writeln('<info>ok</info>'); } catch ( - ArchiveCreateException - | ArchiveNotFoundException - | NotFoundException - | NotPermittedException - | RestoreChunkException $e) { - $this->output->writeln('<error>' . $e->getMessage() . '</error>'); - } + ArchiveCreateException + | ArchiveNotFoundException + | NotFoundException + | NotPermittedException + | RestoreChunkException $e) { + $this->output->writeln('<error>' . $e->getMessage() . '</error>'); + } } $data->setRestoredRoot($root); diff --git a/lib/Command/PointScan.php b/lib/Command/PointScan.php index 0e251fe..f419665 100755 --- a/lib/Command/PointScan.php +++ b/lib/Command/PointScan.php @@ -31,13 +31,13 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use OC\Core\Command\Base; use OCA\Backup\Db\PointRequest; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; use OCA\Backup\Service\ChunkService; use OCA\Backup\Service\OutputService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Traits\TStringTools; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use Symfony\Component\Console\Exception\InvalidArgumentException; @@ -100,7 +100,7 @@ class PointScan extends Base { protected function configure() { $this->setName('backup:point:scan') ->setDescription( - 'Scan a folder containing the data of a restoring point to add it in the list of available restoring point' + 'Scan a folder containing the data of a restoring point to add it in the list of available restoring point' ) ->addOption('owner', '', InputOption::VALUE_REQUIRED, 'owner of the metadata file') ->addOption('file', '', InputOption::VALUE_REQUIRED, 'file_id of the metadata file'); diff --git a/lib/Command/PointUnarchive.php b/lib/Command/PointUnarchive.php index 5fa5bbc..1cde35b 100755 --- a/lib/Command/PointUnarchive.php +++ b/lib/Command/PointUnarchive.php @@ -31,7 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; use OC\Core\Command\Base; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; use OCA\Backup\Exceptions\MetadataException; @@ -44,6 +43,7 @@ use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Exceptions\RestoringPointPackException; use OCA\Backup\Service\OccService; use OCA\Backup\Service\OutputService; +use OCA\Backup\Tools\Exceptions\SignatoryException; use OCP\Files\GenericFileException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; diff --git a/lib/Command/PointUnpack.php b/lib/Command/PointUnpack.php index e4e7cfb..47e0b34 100755 --- a/lib/Command/PointUnpack.php +++ b/lib/Command/PointUnpack.php @@ -31,13 +31,13 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; use OC\Core\Command\Base; use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Service\OutputService; use OCA\Backup\Service\PackService; use OCA\Backup\Service\PointService; use OCA\Backup\Service\RemoteStreamService; +use OCA\Backup\Tools\Exceptions\SignatoryException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Lock\LockedException; diff --git a/lib/Command/PointUpload.php b/lib/Command/PointUpload.php index 58fcd1c..e85c50f 100755 --- a/lib/Command/PointUpload.php +++ b/lib/Command/PointUpload.php @@ -39,7 +39,6 @@ use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Exceptions\RestoringPointPackException; use OCA\Backup\Service\OutputService; use OCA\Backup\Service\PointService; -use OCA\Backup\Service\RemoteService; use OCA\Backup\Service\UploadService; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -60,9 +59,6 @@ class PointUpload extends Base { /** @var PointService */ private $pointService; - /** @var RemoteService */ - private $remoteService; - /** @var UploadService */ private $uploadService; @@ -74,20 +70,17 @@ class PointUpload extends Base { * PointUpload constructor. * * @param PointService $pointService - * @param RemoteService $remoteService * @param UploadService $uploadService * @param OutputService $outputService */ public function __construct( PointService $pointService, - RemoteService $remoteService, UploadService $uploadService, OutputService $outputService ) { parent::__construct(); $this->pointService = $pointService; - $this->remoteService = $remoteService; $this->uploadService = $uploadService; $this->outputService = $outputService; } diff --git a/lib/Command/RemoteAdd.php b/lib/Command/RemoteAdd.php deleted file mode 100755 index f648585..0000000 --- a/lib/Command/RemoteAdd.php +++ /dev/null @@ -1,346 +0,0 @@ -<?php - -declare(strict_types=1); - - -/** - * Nextcloud - Backup now. Restore later. - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Maxence Lange <maxence@artificial-owl.com> - * @copyright 2021, Maxence Lange <maxence@artificial-owl.com> - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -namespace OCA\Backup\Command; - -use ArtificialOwl\MySmallPhpTools\Exceptions\RequestNetworkException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; -use ArtificialOwl\MySmallPhpTools\Exceptions\WellKnownLinkNotFoundException; -use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23WellKnown; -use OC\Core\Command\Base; -use OCA\Backup\AppInfo\Application; -use OCA\Backup\Db\RemoteRequest; -use OCA\Backup\Exceptions\RemoteInstanceDuplicateException; -use OCA\Backup\Exceptions\RemoteInstanceException; -use OCA\Backup\Exceptions\RemoteInstanceNotFoundException; -use OCA\Backup\Exceptions\RemoteInstanceUidException; -use OCA\Backup\Model\RemoteInstance; -use OCA\Backup\Service\ConfigService; -use OCA\Backup\Service\RemoteStreamService; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\ConfirmationQuestion; - -/** - * Class RemoteAdd - * - * @package OCA\Backup\Command - */ -class RemoteAdd extends Base { - use TNC23WellKnown; - - - /** @var RemoteRequest */ - private $remoteRequest; - - /** @var RemoteStreamService */ - private $remoteStreamService; - - /** @var ConfigService */ - private $configService; - - - /** - * RemoteAdd constructor. - * - * @param RemoteRequest $remoteRequest - * @param RemoteStreamService $remoteStreamService - * @param ConfigService $configService - */ - public function __construct( - RemoteRequest $remoteRequest, - RemoteStreamService $remoteStreamService, - ConfigService $configService - ) { - $this->remoteRequest = $remoteRequest; - $this->remoteStreamService = $remoteStreamService; - $this->configService = $configService; - - parent::__construct(); - } - - - /** - * - */ - protected function configure() { - if (!$this->configService->isRemoteEnabled()) { - $this->setHidden(true); - } - - $this->setName('backup:remote:add') - ->setDescription('Add remote instances to store your backups') - ->addArgument('address', InputArgument::REQUIRED, 'address of the remote instance of Nextcloud'); - } - - - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int - * @throws RequestNetworkException - * @throws SignatureException - * @throws WellKnownLinkNotFoundException - * @throws SignatoryException - * @throws RemoteInstanceUidException - * @throws RemoteInstanceDuplicateException - * @throws RemoteInstanceException - */ - protected function execute(InputInterface $input, OutputInterface $output): int { - if (!$this->configService->isRemoteEnabled()) { - throw new RemoteInstanceException('not enabled'); - } - - $address = $input->getArgument('address'); - if (strtolower($address) === RemoteInstance::LOCAL || strtolower($address) === RemoteInstance::ALL) { - throw new RemoteInstanceException($address . ' is a reserved name'); - } - - $resource = $this->getCurrentResourceFromAddress($output, $address); - $this->remoteStreamService->getAppSignatory(); - - $knownInstance = null; - try { - $knownInstance = $this->remoteRequest->getFromHref($resource->g('id')); - } catch (RemoteInstanceNotFoundException $e) { - } - - try { - /** @var RemoteInstance $remoteSignatory */ - $remoteSignatory = $this->remoteStreamService->retrieveSignatory($resource->g('id'), true); - } catch (SignatureException $e) { - throw new SignatureException($address . ' cannot auth its identity: ' . $e->getMessage()); - } - - try { - $duplicateInstance = $this->remoteRequest->getByInstance($address); - if ($duplicateInstance->getId() !== $remoteSignatory->getId()) { - throw new RemoteInstanceDuplicateException( - 'There is already a known instance with same ADDRESS but different HREF. Please remove it first!' - ); - } - } catch (RemoteInstanceNotFoundException $e) { - } - - $remoteSignatory->setInstance($address); - if (!is_null($knownInstance)) { - if ($remoteSignatory->getInstance() !== $knownInstance->getInstance()) { - throw new RemoteInstanceDuplicateException( - 'There is already a known instance with same HREF but different ADDRESS (' - . $knownInstance->getInstance() . '). Please remove it first!' - ); - } - - if ($remoteSignatory->getUid(true) !== $knownInstance->getUid()) { - $output->writeln(''); - $output->writeln('<error>### WARNING ###</error>'); - $output->writeln( - '<error>The instance on ' . $knownInstance->getInstance() - . ' is already known under an other identity!</error>' - ); - $output->writeln('<error>### WARNING ###</error>'); - - $output->writeln(''); - $output->writeln('Continue with this process if you want to store the new identity.'); - $output->writeln('Doing so (and based on the given outgoing/incoming rights): '); - $output->writeln(' - the remote instance with the old identity will loose access to'); - $output->writeln(' this service,'); - $output->writeln(' - the remote instance with the new identity will gain access to'); - $output->writeln( - ' <options=underscore>all backups previously uploaded</> by the previous instance,' - ); - $output->writeln( - ' - your instance will now <options=underscore>upload your local backups</> to this new' - ); - $output->writeln(' remote instance,'); - $output->writeln(' - your instance will not be able to browse any backup on the old'); - $output->writeln(' remote instance,'); - $output->writeln(' - your instance might be able to get access to previous uploaded'); - $output->writeln(' backup if available on the new remote instance'); - $output->writeln(''); - $output->writeln( - '<error>Please CONFIRM with an Administrator from the remote instance before updating any identity.</error>' - ); - $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion( - 'Are you sure you want to continue with the process ? (y/N)', - false, - '/^(y|Y)/i' - ); - - if (!$helper->ask($input, $output, $question)) { - return 0; - } - } - } - - $this->configureRemoteInstance($input, $output, $remoteSignatory, $knownInstance); - $this->saveRemoteInstance($input, $output, $remoteSignatory); - - return 0; - } - - - /** - * @param OutputInterface $output - * @param string $address - * - * @return SimpleDataStore - * @throws RequestNetworkException - * @throws WellKnownLinkNotFoundException - */ - private function getCurrentResourceFromAddress( - OutputInterface $output, - string $address - ): SimpleDataStore { - try { - $webfinger = $this->getWebfinger($address, Application::APP_SUBJECT); - } catch (RequestNetworkException $e) { - throw new RequestNetworkException( - $address - . ' is not reachable or is not a instance of Nextcloud or do not have the Backup App installed' - ); - } - try { - $backupLink = $this->extractLink(Application::APP_REL, $webfinger); - } catch (WellKnownLinkNotFoundException $e) { - throw new WellKnownLinkNotFoundException( - $address - . ' is not a instance of Nextcloud or do not have the Backup App installed and configured' - ); - } - - $output->writeln( - 'Remote instance <info>' . $address . '</info> is using <info>' . $backupLink->getProperty('name') - . ' v' . $backupLink->getProperty('version') . '</info>' - ); - - $resource = $this->getResourceFromLink($backupLink); - $output->writeln('Authentication key: <info>' . $resource->g('uid') . '</info>'); - - return $resource; - } - - - /** - * @param InputInterface $input - * @param OutputInterface $output - * @param RemoteInstance $remoteInstance - * @param RemoteInstance|null $knownInstance - */ - private function configureRemoteInstance( - InputInterface $input, - OutputInterface $output, - RemoteInstance $remoteInstance, - ?RemoteInstance $knownInstance - ): void { - $outgoing = !(is_null($knownInstance)) && $knownInstance->isOutgoing(); - $incoming = !(is_null($knownInstance)) && $knownInstance->isIncoming(); - - $output->writeln(''); - $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion( - 'Do you want to use <info>' . $remoteInstance->getInstance() - . '</info> as a remote instance to store your backup files ? ' - . ($outgoing ? '(Y/n)' : '(y/N)'), - $outgoing, - '/^(y|Y)/i' - ); - - $remoteInstance->setOutgoing($helper->ask($input, $output, $question)); - - $question = new ConfirmationQuestion( - 'Do you want to allow <info>' . $remoteInstance->getInstance() - . '</info> to store its backup files on your own instance ? ' - . ($incoming ? '(Y/n)' : '(y/N)'), - $incoming, - '/^(y|Y)/i' - ); - - $remoteInstance->setIncoming($helper->ask($input, $output, $question)); - } - - - /** - * @throws RemoteInstanceUidException - */ - private function saveRemoteInstance( - InputInterface $input, - OutputInterface $output, - RemoteInstance $remoteInstance - ): void { - $output->writeln(''); - $output->writeln( - 'Using remote instance to store local backups: ' . ($remoteInstance->isOutgoing( - ) ? '<info>yes</info>' : '<comment>no</comment>') - ); - $output->writeln( - 'Locally storing backups from remote instance: ' . ($remoteInstance->isIncoming( - ) ? '<info>yes</info>' : '<comment>no</comment>') - ); - - $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion( - 'Please confirm those settings <info>(y/N)</info> ', - false, - '/^(y|Y)/i' - ); - - if (!$helper->ask($input, $output, $question)) { - return; - } - - $this->remoteRequest->insertOrUpdate($remoteInstance); - - $output->writeln(''); - $output->writeln('<error>Important note</error>: '); - $output->writeln('Uploaded backup are encrypted which is good, don\'t you think ?'); - $output->writeln( - 'However, it also means that <options=bold>if you loose the Encryption Key, your backup will be totally useless</>' - ); - $output->writeln(''); - $output->writeln('It is advised to export the setup of the Backup App in the file of your choice.'); - $output->writeln( - 'Keep in mind that with this file, any installation of Nextcloud can access your backup,' - ); - $output->writeln('restore them and access the data of your users'); - $output->writeln( - 'While this is an option, ts is also advised to force the creation of a key to encrypt the content of the file:' - ); - $output->writeln(''); - $output->writeln(' ./occ backup:setup:export [--key] > ~/backup_setup.json'); - $output->writeln(''); - } -} diff --git a/lib/Command/RemoteList.php b/lib/Command/RemoteList.php deleted file mode 100755 index 0db65b8..0000000 --- a/lib/Command/RemoteList.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php - -declare(strict_types=1); - - -/** - * Nextcloud - Backup now. Restore later. - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Maxence Lange <maxence@artificial-owl.com> - * @copyright 2021, Maxence Lange <maxence@artificial-owl.com> - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -namespace OCA\Backup\Command; - -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; -use OC\Core\Command\Base; -use OCA\Backup\Db\RemoteRequest; -use OCA\Backup\Exceptions\RemoteInstanceException; -use OCA\Backup\Model\RemoteInstance; -use OCA\Backup\Service\ConfigService; -use OCA\Backup\Service\RemoteStreamService; -use Symfony\Component\Console\Helper\Table; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Class RemoteList - * - * @package OCA\Backup\Command - */ -class RemoteList extends Base { - - - /** @var RemoteRequest */ - private $remoteRequest; - - /** @var RemoteStreamService */ - private $remoteStreamService; - - /** @var ConfigService */ - private $configService; - - - /** - * RemoteList constructor. - * - * @param RemoteRequest $remoteRequest - * @param RemoteStreamService $remoteStreamService - * @param ConfigService $configService - */ - public function __construct( - RemoteRequest $remoteRequest, - RemoteStreamService $remoteStreamService, - ConfigService $configService - ) { - $this->remoteRequest = $remoteRequest; - $this->remoteStreamService = $remoteStreamService; - $this->configService = $configService; - - parent::__construct(); - } - - - /** - * - */ - protected function configure() { - if (!$this->configService->isRemoteEnabled()) { - $this->setHidden(true); - } - - $this->setName('backup:remote:list') - ->setDescription('Listing configured remote instances'); - } - - - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int - * @throws RemoteInstanceException - */ - protected function execute(InputInterface $input, OutputInterface $output): int { - if (!$this->configService->isRemoteEnabled()) { - throw new RemoteInstanceException('not enabled'); - } - - $output = new ConsoleOutput(); - $output = $output->section(); - $table = new Table($output); - $table->setHeaders( - ['Address', 'Stored Uid', 'Current Uid', 'Href', 'Incoming data', 'Outgoing data'] - ); - $table->render(); - - foreach ($this->remoteRequest->getAll() as $remoteInstance) { - $color = 'error'; - $currentUid = 'not available'; - - /** @var RemoteInstance $current */ - try { - $current = $this->remoteStreamService->retrieveSignatory($remoteInstance->getId()); - $currentUid = $current->getUid(true); - if ($remoteInstance->getUid(true) === $currentUid) { - $color = 'info'; - } - } catch (SignatoryException | SignatureException $e) { - } - - $table->appendRow( - [ - $remoteInstance->getInstance(), - $remoteInstance->getUid(true), - '<' . $color . '>' . $currentUid . '</' . $color . '>', - $remoteInstance->getId(), - ($remoteInstance->isIncoming() ? '<info>yes</info>' : '<comment>no</comment'), - ($remoteInstance->isOutgoing() ? '<info>yes</info>' : '<comment>no</comment') - ] - ); - } - - return 0; - } -} diff --git a/lib/Command/RemoteRemove.php b/lib/Command/RemoteRemove.php deleted file mode 100755 index ece3e0c..0000000 --- a/lib/Command/RemoteRemove.php +++ /dev/null @@ -1,115 +0,0 @@ -<?php - -declare(strict_types=1); - - -/** - * Nextcloud - Backup now. Restore later. - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Maxence Lange <maxence@artificial-owl.com> - * @copyright 2021, Maxence Lange <maxence@artificial-owl.com> - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -namespace OCA\Backup\Command; - -use OC\Core\Command\Base; -use OCA\Backup\Db\RemoteRequest; -use OCA\Backup\Exceptions\RemoteInstanceException; -use OCA\Backup\Exceptions\RemoteInstanceNotFoundException; -use OCA\Backup\Service\ConfigService; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Class RemoteRemove - * - * @package OCA\Backup\Command - */ -class RemoteRemove extends Base { - - - /** @var RemoteRequest */ - private $remoteRequest; - - /** @var ConfigService */ - private $configService; - - - /** - * RemoteRemove constructor. - * - * @param RemoteRequest $remoteRequest - * @param ConfigService $configService - */ - public function __construct( - RemoteRequest $remoteRequest, - ConfigService $configService - ) { - $this->remoteRequest = $remoteRequest; - $this->configService = $configService; - - parent::__construct(); - } - - - /** - * - */ - protected function configure() { - if (!$this->configService->isRemoteEnabled()) { - $this->setHidden(true); - } - - $this->setName('backup:remote:remove') - ->setDescription('Removing remote instances from database') - ->addArgument('address', InputArgument::REQUIRED, 'address of the remote instance of Nextcloud'); - } - - - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int - * @throws RemoteInstanceNotFoundException - * @throws RemoteInstanceException - */ - protected function execute(InputInterface $input, OutputInterface $output): int { - if (!$this->configService->isRemoteEnabled()) { - throw new RemoteInstanceException('not enabled'); - } - - $address = $input->getArgument('address'); - - try { - $this->remoteRequest->getByInstance($address); - } catch (RemoteInstanceNotFoundException $e) { - throw new RemoteInstanceNotFoundException('Unknown address'); - } - - $this->remoteRequest->remove($address); - $output->writeln('instance removed.'); - - return 0; - } -} diff --git a/lib/Command/Reset.php b/lib/Command/Reset.php index 7095da3..4a3a7cc 100755 --- a/lib/Command/Reset.php +++ b/lib/Command/Reset.php @@ -89,7 +89,7 @@ class Reset extends Base { $this->setName('backup:reset') ->setDescription('Remove all data related to the Backup App') ->addOption( - 'uninstall', '', InputOption::VALUE_NONE, 'Also uninstall the app from the instance' + 'uninstall', '', InputOption::VALUE_NONE, 'Also uninstall the app from the instance' ); } diff --git a/lib/Command/SetupImport.php b/lib/Command/SetupImport.php index 0d90dd2..0aecde8 100755 --- a/lib/Command/SetupImport.php +++ b/lib/Command/SetupImport.php @@ -31,8 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Command; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use Exception; use OC\Core\Command\Base; use OCA\Backup\Db\RemoteRequest; @@ -43,6 +41,8 @@ use OCA\Backup\Model\RemoteInstance; use OCA\Backup\Service\ConfigService; use OCA\Backup\Service\EncryptService; use OCA\Backup\Service\RemoteStreamService; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; use SodiumException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -55,7 +55,7 @@ use Symfony\Component\Console\Output\OutputInterface; */ class SetupImport extends Base { use TArrayTools; - use TNC23Deserialize; + use TDeserialize; /** @var RemoteRequest */ diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index 30c95c7..8045f85 100755 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -31,12 +31,7 @@ declare(strict_types=1); namespace OCA\Backup\Controller; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Controller; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use Exception; -use OC\AppFramework\Http; use OC\Files\Node\File; use OC\Files\Node\Folder; use OC\User\NoUserException; @@ -54,6 +49,10 @@ use OCA\Backup\Service\ExternalFolderService; use OCA\Backup\Service\FilesService; use OCA\Backup\Service\PointService; use OCA\Backup\Service\RestoreService; +use OCA\Backup\Tools\Exceptions\SignatureException; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSException; use OCP\AppFramework\OCSController; @@ -70,9 +69,8 @@ use OCP\Lock\LockedException; * @package OCA\Backup\Controller */ class LocalController extends OcsController { - use TNC23Controller; - use TNC23Logger; - use TNC23Deserialize; + use TNCLogger; + use TDeserialize; /** @var IUserSession */ diff --git a/lib/Controller/RemoteController.php b/lib/Controller/RemoteController.php deleted file mode 100755 index cb79d89..0000000 --- a/lib/Controller/RemoteController.php +++ /dev/null @@ -1,419 +0,0 @@ -<?php - -declare(strict_types=1); - - -/** - * Nextcloud - Backup now. Restore later. - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Maxence Lange <maxence@artificial-owl.com> - * @copyright 2021, Maxence Lange <maxence@artificial-owl.com> - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -namespace OCA\Backup\Controller; - -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidOriginException; -use ArtificialOwl\MySmallPhpTools\Exceptions\JsonNotRequestedException; -use ArtificialOwl\MySmallPhpTools\Exceptions\MalformedArrayException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23SignedRequest; -use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Controller; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use Exception; -use OC; -use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException; -use OCA\Backup\AppInfo\Application; -use OCA\Backup\Exceptions\RemoteRequestException; -use OCA\Backup\IRemoteRequest; -use OCA\Backup\Model\RemoteInstance; -use OCA\Backup\RemoteRequest\CreateRestoringPoint; -use OCA\Backup\RemoteRequest\DeleteRestoringPoint; -use OCA\Backup\RemoteRequest\DownloadRestoringChunk; -use OCA\Backup\RemoteRequest\GetRestoringPoint; -use OCA\Backup\RemoteRequest\ListRestoringPoint; -use OCA\Backup\RemoteRequest\UpdateRestoringPoint; -use OCA\Backup\RemoteRequest\UploadRestoringChunk; -use OCA\Backup\Service\RemoteStreamService; -use OCP\AppFramework\Controller; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\DataResponse; -use OCP\IRequest; -use ReflectionClass; -use ReflectionException; - -/** - * Class RemoteController - * - * @package OCA\Backup\Controller - */ -class RemoteController extends Controller { - use TNC23Controller; - use TNC23Logger; - - - /** @var RemoteStreamService */ - private $remoteStreamService; - - - /** - * RemoteController constructor. - * - * @param string $appName - * @param IRequest $request - * @param RemoteStreamService $remoteStreamService - */ - public function __construct( - string $appName, - IRequest $request, - RemoteStreamService $remoteStreamService - ) { - parent::__construct($appName, $request); - - $this->remoteStreamService = $remoteStreamService; - - $this->setup('app', Application::APP_ID); - $this->setupArray('enforceSignatureHeaders', ['digest', 'content-length']); - } - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @return DataResponse - * @throws NotLoggedInException - * @throws SignatoryException - */ - public function appService(): DataResponse { - try { - $this->publicPageJsonLimited(); - } catch (JsonNotRequestedException $e) { - return new DataResponse(); - } - - $signatory = $this->remoteStreamService->getAppSignatory(false, $this->request->getParam('auth', '')); - - return new DataResponse($signatory); - } - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @return DataResponse - */ - public function createRestoringPoint(): DataResponse { - try { - $request = $this->extractRequest(CreateRestoringPoint::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @return DataResponse - */ - public function listRestoringPoint(): DataResponse { - try { - $request = $this->extractRequest(ListRestoringPoint::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @param string $pointId - * - * @return DataResponse - */ - public function getRestoringPoint(string $pointId): DataResponse { - try { - $request = $this->extractRequest(GetRestoringPoint::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @param string $pointId - * - * @return DataResponse - */ - public function updateRestoringPoint(string $pointId): DataResponse { - try { - $request = $this->extractRequest(UpdateRestoringPoint::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @param string $pointId - * - * @return DataResponse - */ - public function deleteRestoringPoint(string $pointId): DataResponse { - try { - $request = $this->extractRequest(DeleteRestoringPoint::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @param string $pointId - * - * @return DataResponse - */ - public function healthRestoringPoint(string $pointId): DataResponse { - try { - $request = $this->extractRequest(GetRestoringPoint::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->config(new SimpleDataStore(['refreshHealth' => true])); - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @param string $pointId - * @param string $chunkName - * - * @return DataResponse - */ - public function downloadRestoringPoint(string $pointId, string $chunkName): DataResponse { - try { - $request = $this->extractRequest(DownloadRestoringChunk::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - /** - * @PublicPage - * @NoCSRFRequired - * - * @param string $pointId - * @param string $chunkName - * - * @return DataResponse - */ - public function uploadRestoringChunk(string $pointId, string $chunkName): DataResponse { - try { - $request = $this->extractRequest(UploadRestoringChunk::class); - } catch (Exception $e) { - return $this->exceptionResponse($e, Http::STATUS_UNAUTHORIZED); - } - - try { - $request->execute(); - - return new DataResponse($request->getOutcome()); - } catch (Exception $e) { - $this->e($e, ['request' => $request]); - - return $this->exceptionResponse($e); - } - } - - - /** - * @param string $class - * - * @return IRemoteRequest - * @throws RemoteRequestException - * @throws SignatoryException - * @throws InvalidOriginException - * @throws MalformedArrayException - * @throws SignatureException - */ - private function extractRequest(string $class = ''): ?IRemoteRequest { - $signed = $this->remoteStreamService->incomingSignedRequest(); - $this->confirmRemoteInstance($signed); - - if ($class === '') { - return null; - } - - try { - $test = new ReflectionClass($class); - } catch (ReflectionException $e) { - throw new RemoteRequestException('ReflectionException with ' . $class . ': ' . $e->getMessage()); - } - - if (!in_array(IRemoteRequest::class, $test->getInterfaceNames())) { - throw new RemoteRequestException($class . ' does not implements IRemoteRequest'); - } - - $item = OC::$server->get($class); - if (!($item instanceof IRemoteRequest)) { - throw new RemoteRequestException($class . ' not an IRemoteRequest'); - } - - $item->import(json_decode($signed->getBody(), true)); - $item->setSignedRequest($signed); - - return $item; - } - - - /** - * @param NC23SignedRequest $signedRequest - * - * @return RemoteInstance - * @throws SignatoryException - */ - private function confirmRemoteInstance(NC23SignedRequest $signedRequest): RemoteInstance { - /** @var RemoteInstance $signatory */ - $signatory = $signedRequest->getSignatory(); - - if (!$signatory instanceof RemoteInstance) { - $this->debug('Signatory is not a known RemoteInstance', ['signedRequest' => $signedRequest]); - throw new SignatoryException('Could not confirm identity'); - } - - if (!$signatory->isIncoming()) { - throw new SignatoryException('Remote instance is not configured as Incoming'); - } - - return $signatory; - } - - - /** - * @param Exception $e - * @param int $httpErrorCode - * - * @return DataResponse - */ - public function exceptionResponse( - Exception $e, - int $httpErrorCode = Http::STATUS_BAD_REQUEST - ): DataResponse { - return new DataResponse( - [ - 'message' => $e->getMessage(), - 'code' => $e->getCode() - ], - ($e->getCode() > 0) ? $e->getCode() : $httpErrorCode - ); - } -} diff --git a/lib/Cron/Backup.php b/lib/Cron/Backup.php index adb023a..6007ce7 100644 --- a/lib/Cron/Backup.php +++ b/lib/Cron/Backup.php @@ -31,12 +31,12 @@ declare(strict_types=1); namespace OCA\Backup\Cron; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OC\BackgroundJob\TimedJob; use OCA\Backup\Exceptions\JobsTimeSlotException; use OCA\Backup\Service\ConfigService; use OCA\Backup\Service\CronService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Traits\TNCLogger; use Psr\Log\LoggerInterface; use Throwable; @@ -46,7 +46,7 @@ use Throwable; * @package OCA\Backup\Cron */ class Backup extends TimedJob { - use TNC23Logger; + use TNCLogger; /** @var PointService */ diff --git a/lib/Cron/Event.php b/lib/Cron/Event.php index e9d35f5..7527ca5 100644 --- a/lib/Cron/Event.php +++ b/lib/Cron/Event.php @@ -31,7 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Cron; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OC\BackgroundJob\TimedJob; use OCA\Backup\Db\EventRequest; use OCA\Backup\Model\BackupEvent; @@ -39,6 +38,7 @@ use OCA\Backup\Service\ConfigService; use OCA\Backup\Service\CronService; use OCA\Backup\Service\FilesService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class Event diff --git a/lib/Db/ChangesRequestBuilder.php b/lib/Db/ChangesRequestBuilder.php index 2902978..1a5691a 100644 --- a/lib/Db/ChangesRequestBuilder.php +++ b/lib/Db/ChangesRequestBuilder.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Db; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\RowNotFoundException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\RowNotFoundException; use OCA\Backup\Exceptions\ChangedFileNotFoundException; use OCA\Backup\Model\ChangedFile; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class ChangesRequestBuilder diff --git a/lib/Db/CoreQueryBuilder.php b/lib/Db/CoreQueryBuilder.php index 2c5338d..ba19753 100644 --- a/lib/Db/CoreQueryBuilder.php +++ b/lib/Db/CoreQueryBuilder.php @@ -31,14 +31,14 @@ declare(strict_types=1); namespace OCA\Backup\Db; -use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc23\NC23ExtendedQueryBuilder; +use OCA\Backup\Tools\Db\ExtendedQueryBuilder; /** * Class CoreQueryBuilder * * @package OCA\Backup\Db */ -class CoreQueryBuilder extends NC23ExtendedQueryBuilder { +class CoreQueryBuilder extends ExtendedQueryBuilder { /** diff --git a/lib/Db/EventRequestBuilder.php b/lib/Db/EventRequestBuilder.php index 3517ec0..15d080c 100644 --- a/lib/Db/EventRequestBuilder.php +++ b/lib/Db/EventRequestBuilder.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Db; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\RowNotFoundException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OCA\Backup\Exceptions\BackupEventNotFoundException; use OCA\Backup\Model\BackupEvent; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\RowNotFoundException; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class EventRequestBuilder diff --git a/lib/Db/ExternalFolderRequestBuilder.php b/lib/Db/ExternalFolderRequestBuilder.php index 9c0a128..a682ee1 100644 --- a/lib/Db/ExternalFolderRequestBuilder.php +++ b/lib/Db/ExternalFolderRequestBuilder.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Db; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\RowNotFoundException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; use OCA\Backup\Model\ExternalFolder; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\RowNotFoundException; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class ExternalFolderRequestBuilder diff --git a/lib/Db/PointRequestBuilder.php b/lib/Db/PointRequestBuilder.php index 01fcb68..19bb08f 100644 --- a/lib/Db/PointRequestBuilder.php +++ b/lib/Db/PointRequestBuilder.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Db; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\RowNotFoundException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\RowNotFoundException; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class BackupRequestBuilder diff --git a/lib/Db/RemoteRequest.php b/lib/Db/RemoteRequest.php index b05b471..411af42 100644 --- a/lib/Db/RemoteRequest.php +++ b/lib/Db/RemoteRequest.php @@ -111,6 +111,7 @@ class RemoteRequest extends RemoteRequestBuilder { /** + * @return RemoteInstance * @throws RemoteInstanceNotFoundException */ public function getByInstance(string $instance): RemoteInstance { diff --git a/lib/Db/RemoteRequestBuilder.php b/lib/Db/RemoteRequestBuilder.php index ceaca1c..aee2a14 100644 --- a/lib/Db/RemoteRequestBuilder.php +++ b/lib/Db/RemoteRequestBuilder.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Db; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\RowNotFoundException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OCA\Backup\Exceptions\RemoteInstanceNotFoundException; use OCA\Backup\Model\RemoteInstance; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\RowNotFoundException; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class RemoteRequestBuilder diff --git a/lib/Db/RestoringDataRequestBuilder.php b/lib/Db/RestoringDataRequestBuilder.php index d9859de..252bb71 100644 --- a/lib/Db/RestoringDataRequestBuilder.php +++ b/lib/Db/RestoringDataRequestBuilder.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Db; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\RowNotFoundException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OCA\Backup\Exceptions\RestoringDataNotFoundException; use OCA\Backup\Model\RestoringData; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\RowNotFoundException; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class RestoringDataRequestBuilder diff --git a/lib/Handlers/WebfingerHandler.php b/lib/Handlers/WebfingerHandler.php index 8bfa078..d9f612e 100644 --- a/lib/Handlers/WebfingerHandler.php +++ b/lib/Handlers/WebfingerHandler.php @@ -31,12 +31,12 @@ declare(strict_types=1); namespace OCA\Backup\Handlers; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OC\URLGenerator; use OCA\Backup\AppInfo\Application; use OCA\Backup\Service\ConfigService; use OCA\Backup\Service\RemoteStreamService; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Traits\TArrayTools; use OCP\Http\WellKnown\IHandler; use OCP\Http\WellKnown\IRequestContext; use OCP\Http\WellKnown\IResponse; diff --git a/lib/IRemoteRequest.php b/lib/IRemoteRequest.php index 5517281..e0c7144 100644 --- a/lib/IRemoteRequest.php +++ b/lib/IRemoteRequest.php @@ -31,9 +31,9 @@ declare(strict_types=1); namespace OCA\Backup; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23SignedRequest; -use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Model\NCSignedRequest; +use OCA\Backup\Tools\Model\SimpleDataStore; /** * Interface IRemoteRequest @@ -43,9 +43,9 @@ use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; interface IRemoteRequest extends IDeserializable { /** - * @param NC23SignedRequest $signedRequest + * @param NCSignedRequest $signedRequest */ - public function setSignedRequest(NC23SignedRequest $signedRequest): void; + public function setSignedRequest(NCSignedRequest $signedRequest): void; /** * @param SimpleDataStore $config diff --git a/lib/Listeners/NodeEvent.php b/lib/Listeners/NodeEvent.php index a1b75e3..7a267b4 100644 --- a/lib/Listeners/NodeEvent.php +++ b/lib/Listeners/NodeEvent.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Listeners; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OCA\Backup\AppInfo\Application; use OCA\Backup\Model\ChangedFile; use OCA\Backup\Service\ConfigService; use OCA\Backup\Service\FilesService; +use OCA\Backup\Tools\Traits\TNCLogger; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\Files\Events\Node\NodeCreatedEvent; @@ -49,7 +49,7 @@ use OCP\Files\NotFoundException; * @package OCA\Backup\Listeners */ class NodeEvent implements IEventListener { - use TNC23Logger; + use TNCLogger; /** @var FilesService */ diff --git a/lib/Model/ArchiveFile.php b/lib/Model/ArchiveFile.php index 8641c8e..f0b8c85 100644 --- a/lib/Model/ArchiveFile.php +++ b/lib/Model/ArchiveFile.php @@ -31,8 +31,8 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; use JsonSerializable; /** diff --git a/lib/Model/BackupEvent.php b/lib/Model/BackupEvent.php index a858dad..5e69ec7 100644 --- a/lib/Model/BackupEvent.php +++ b/lib/Model/BackupEvent.php @@ -31,18 +31,18 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc23\INC23QueryRow; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use JsonSerializable; +use OCA\Backup\Tools\Db\IQueryRow; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TStringTools; /** * Class BackupEvent * * @package OCA\Backup\Model */ -class BackupEvent implements JsonSerializable, INC23QueryRow, IDeserializable { +class BackupEvent implements JsonSerializable, IQueryRow, IDeserializable { use TArrayTools; use TStringTools; @@ -195,7 +195,7 @@ class BackupEvent implements JsonSerializable, INC23QueryRow, IDeserializable { * * @return ExternalFolder */ - public function importFromDatabase(array $data): INC23QueryRow { + public function importFromDatabase(array $data): IQueryRow { $this->setId($this->getInt('id', $data)) ->setAuthor($this->get('author', $data)) ->setType($this->get('type', $data)) diff --git a/lib/Model/ChangedFile.php b/lib/Model/ChangedFile.php index adf7662..002e549 100644 --- a/lib/Model/ChangedFile.php +++ b/lib/Model/ChangedFile.php @@ -31,16 +31,16 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc23\INC23QueryRow; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use JsonSerializable; +use OCA\Backup\Tools\Db\IQueryRow; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class ChangedFile * * @package OCA\Backup\Model */ -class ChangedFile implements INC23QueryRow, JsonSerializable { +class ChangedFile implements IQueryRow, JsonSerializable { use TArrayTools; @@ -105,9 +105,9 @@ class ChangedFile implements INC23QueryRow, JsonSerializable { /** * @param array $data * - * @return INC23QueryRow + * @return IQueryRow */ - public function importFromDatabase(array $data): INC23QueryRow { + public function importFromDatabase(array $data): IQueryRow { $this->setPath($this->get('path', $data)); $this->setHash($this->get('hash', $data)); diff --git a/lib/Model/ChunkPartHealth.php b/lib/Model/ChunkPartHealth.php index 2a92f28..af2194a 100644 --- a/lib/Model/ChunkPartHealth.php +++ b/lib/Model/ChunkPartHealth.php @@ -31,9 +31,9 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use JsonSerializable; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class ChunkPartHealth diff --git a/lib/Model/ExternalFolder.php b/lib/Model/ExternalFolder.php index e834547..a3ad8b7 100644 --- a/lib/Model/ExternalFolder.php +++ b/lib/Model/ExternalFolder.php @@ -31,20 +31,20 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc23\INC23QueryRow; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use JsonSerializable; use OC\Files\Node\Folder; +use OCA\Backup\Tools\Db\IQueryRow; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TStringTools; /** * Class ExternalFolder * * @package OCA\Backup\Model */ -class ExternalFolder implements JsonSerializable, INC23QueryRow, IDeserializable { +class ExternalFolder implements JsonSerializable, IQueryRow, IDeserializable { use TArrayTools; use TStringTools; @@ -159,7 +159,7 @@ class ExternalFolder implements JsonSerializable, INC23QueryRow, IDeserializable * * @return ExternalFolder */ - public function importFromDatabase(array $data): INC23QueryRow { + public function importFromDatabase(array $data): IQueryRow { $this->setStorageId($this->getInt('storage_id', $data)) ->setRoot($this->get('root', $data)); diff --git a/lib/Model/RemoteInstance.php b/lib/Model/RemoteInstance.php index 1902bff..bd09b84 100644 --- a/lib/Model/RemoteInstance.php +++ b/lib/Model/RemoteInstance.php @@ -31,20 +31,20 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc23\INC23QueryRow; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23Signatory; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use JsonSerializable; use OCA\Backup\Exceptions\RemoteInstanceNotFoundException; use OCA\Backup\Exceptions\RemoteInstanceUidException; +use OCA\Backup\Tools\Db\IQueryRow; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Model\NCSignatory; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class AppService * * @package OCA\Backup\Model */ -class RemoteInstance extends NC23Signatory implements INC23QueryRow, IDeserializable, JsonSerializable { +class RemoteInstance extends NCSignatory implements IQueryRow, IDeserializable, JsonSerializable { use TArrayTools; @@ -310,8 +310,6 @@ class RemoteInstance extends NC23Signatory implements INC23QueryRow, IDeserializ } - - /** * @param string $RPDelete * @@ -468,10 +466,10 @@ class RemoteInstance extends NC23Signatory implements INC23QueryRow, IDeserializ /** * @param array $data * - * @return NC23Signatory + * @return NCSignatory */ - public function importSignatory(array $data): NC23Signatory { - parent::importSignatory($data); + public function importSignatory(array $data): self { +// parent::importSignatory($data); $this->setRoot($this->get(self::ROOT, $data)) ->setRPList($this->get(self::RP_LIST, $data)) @@ -540,7 +538,7 @@ class RemoteInstance extends NC23Signatory implements INC23QueryRow, IDeserializ * @return self * @throws RemoteInstanceNotFoundException */ - public function importFromDatabase(array $data): INC23QueryRow { + public function importFromDatabase(array $data): IQueryRow { if ($this->getInt('id', $data) === 0) { throw new RemoteInstanceNotFoundException(); } diff --git a/lib/Model/RestoringChunk.php b/lib/Model/RestoringChunk.php index 16f4497..7c5b463 100644 --- a/lib/Model/RestoringChunk.php +++ b/lib/Model/RestoringChunk.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use JsonSerializable; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TStringTools; /** * Class RestoringChunk @@ -45,7 +45,7 @@ use JsonSerializable; class RestoringChunk implements JsonSerializable, IDeserializable { use TArrayTools; use TStringTools; - use TNC23Deserialize; + use TDeserialize; /** @var string */ diff --git a/lib/Model/RestoringChunkPart.php b/lib/Model/RestoringChunkPart.php index 80d6d5d..c6fd8a2 100644 --- a/lib/Model/RestoringChunkPart.php +++ b/lib/Model/RestoringChunkPart.php @@ -31,10 +31,10 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use JsonSerializable; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TStringTools; /** * Class RestoringChunkPart diff --git a/lib/Model/RestoringData.php b/lib/Model/RestoringData.php index 12c270a..dc5bfda 100644 --- a/lib/Model/RestoringData.php +++ b/lib/Model/RestoringData.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use JsonSerializable; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TStringTools; /** * Class RestoringChunk @@ -45,7 +45,7 @@ use JsonSerializable; class RestoringData implements IDeserializable, JsonSerializable { use TArrayTools; use TStringTools; - use TNC23Deserialize; + use TDeserialize; public const INTERNAL_DATA = 0; diff --git a/lib/Model/RestoringHealth.php b/lib/Model/RestoringHealth.php index f66d15b..79d3f6f 100644 --- a/lib/Model/RestoringHealth.php +++ b/lib/Model/RestoringHealth.php @@ -31,14 +31,14 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use JsonSerializable; use OCA\Backup\AppInfo\Application; use OCA\Backup\Exceptions\RestoringChunkPartNotFoundException; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; /** * Class RestoringHealth @@ -47,8 +47,8 @@ use OCA\Backup\Exceptions\RestoringChunkPartNotFoundException; */ class RestoringHealth implements IDeserializable, JsonSerializable { use TArrayTools; - use TNC23Deserialize; - use TNC23Logger; + use TDeserialize; + use TNCLogger; public const STATUS_ISSUE = 0; diff --git a/lib/Model/RestoringPoint.php b/lib/Model/RestoringPoint.php index 6f80e37..3f8f856 100644 --- a/lib/Model/RestoringPoint.php +++ b/lib/Model/RestoringPoint.php @@ -31,16 +31,16 @@ declare(strict_types=1); namespace OCA\Backup\Model; -use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc23\INC23QueryRow; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\ISignedModel; -use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use JsonSerializable; use OCA\Backup\Exceptions\RestoringDataNotFoundException; +use OCA\Backup\Tools\Db\IQueryRow; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\ISignedModel; +use OCA\Backup\Tools\Model\SimpleDataStore; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; use OCA\Backup\Wrappers\AppDataRootWrapper; use OCP\Files\SimpleFS\ISimpleFolder; @@ -49,10 +49,10 @@ use OCP\Files\SimpleFS\ISimpleFolder; * * @package OCA\Backup\Model */ -class RestoringPoint implements IDeserializable, INC23QueryRow, ISignedModel, JsonSerializable { +class RestoringPoint implements IDeserializable, IQueryRow, ISignedModel, JsonSerializable { use TArrayTools; - use TNC23Deserialize; - use TNC23Logger; + use TDeserialize; + use TNCLogger; public const STATUS_UNPACKED = 0; @@ -615,10 +615,10 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, ISignedModel, Js /** * @param array $data * - * @return INC23QueryRow + * @return IQueryRow * @throws InvalidItemException */ - public function importFromDatabase(array $data): INC23QueryRow { + public function importFromDatabase(array $data): IQueryRow { $this->setId($this->get('uid', $data)) ->setInstance($this->get('instance', $data)) ->setParent($this->get('parent', $data)) diff --git a/lib/RemoteRequest/CoreRequest.php b/lib/RemoteRequest/CoreRequest.php index 561c2ba..8bf5a5f 100644 --- a/lib/RemoteRequest/CoreRequest.php +++ b/lib/RemoteRequest/CoreRequest.php @@ -31,8 +31,8 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23SignedRequest; -use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; +use OCA\Backup\Tools\Model\NCSignedRequest; +use OCA\Backup\Tools\Model\SimpleDataStore; /** * Class RemoteRequest @@ -42,7 +42,7 @@ use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; class CoreRequest { - /** @var NC23SignedRequest */ + /** @var NCSignedRequest */ private $signedRequest; /** @var SimpleDataStore */ @@ -61,16 +61,16 @@ class CoreRequest { /** - * @param NC23SignedRequest $signedRequest + * @param NCSignedRequest $signedRequest */ - public function setSignedRequest(NC23SignedRequest $signedRequest): void { + public function setSignedRequest(NCSignedRequest $signedRequest): void { $this->signedRequest = $signedRequest; } /** - * @return NC23SignedRequest + * @return NCSignedRequest */ - public function getSignedRequest(): NC23SignedRequest { + public function getSignedRequest(): NCSignedRequest { return $this->signedRequest; } diff --git a/lib/RemoteRequest/CreateRestoringPoint.php b/lib/RemoteRequest/CreateRestoringPoint.php index 5c535c6..3a9b8d0 100644 --- a/lib/RemoteRequest/CreateRestoringPoint.php +++ b/lib/RemoteRequest/CreateRestoringPoint.php @@ -31,10 +31,8 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\IDeserializable; use OCA\Backup\AppInfo\Application; use OCA\Backup\Db\PointRequest; use OCA\Backup\Exceptions\RestoringPointNotFoundException; @@ -42,6 +40,8 @@ use OCA\Backup\IRemoteRequest; use OCA\Backup\Model\RemoteInstance; use OCA\Backup\Model\RestoringPoint; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -51,8 +51,8 @@ use OCP\Files\NotPermittedException; * @package OCA\Backup\RemoteRequest */ class CreateRestoringPoint extends CoreRequest implements IRemoteRequest { - use TNC23Deserialize; - use TNC23Logger; + use TDeserialize; + use TNCLogger; /** @var PointRequest */ diff --git a/lib/RemoteRequest/DeleteRestoringPoint.php b/lib/RemoteRequest/DeleteRestoringPoint.php index 923ca96..34ac745 100644 --- a/lib/RemoteRequest/DeleteRestoringPoint.php +++ b/lib/RemoteRequest/DeleteRestoringPoint.php @@ -31,15 +31,15 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OCA\Backup\AppInfo\Application; use OCA\Backup\Db\PointRequest; use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\IRemoteRequest; use OCA\Backup\Model\RemoteInstance; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -49,8 +49,8 @@ use OCP\Files\NotPermittedException; * @package OCA\Backup\RemoteRequest */ class DeleteRestoringPoint extends CoreRequest implements IRemoteRequest { - use TNC23Logger; - use TNC23Deserialize; + use TNCLogger; + use TDeserialize; /** @var PointRequest */ diff --git a/lib/RemoteRequest/DownloadRestoringChunk.php b/lib/RemoteRequest/DownloadRestoringChunk.php index f7b08e8..4ba5d81 100644 --- a/lib/RemoteRequest/DownloadRestoringChunk.php +++ b/lib/RemoteRequest/DownloadRestoringChunk.php @@ -31,10 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OCA\Backup\AppInfo\Application; use OCA\Backup\Exceptions\RestoringChunkNotFoundException; use OCA\Backup\Exceptions\RestoringPointNotFoundException; @@ -44,6 +40,10 @@ use OCA\Backup\Model\RestoringChunkPart; use OCA\Backup\Service\ChunkService; use OCA\Backup\Service\PackService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -53,8 +53,8 @@ use OCP\Files\NotPermittedException; * @package OCA\Backup\RemoteRequest */ class DownloadRestoringChunk extends CoreRequest implements IRemoteRequest { - use TNC23Deserialize; - use TNC23Logger; + use TDeserialize; + use TNCLogger; /** @var PointService */ diff --git a/lib/RemoteRequest/GetRestoringPoint.php b/lib/RemoteRequest/GetRestoringPoint.php index 8a471d5..75cc86a 100644 --- a/lib/RemoteRequest/GetRestoringPoint.php +++ b/lib/RemoteRequest/GetRestoringPoint.php @@ -31,15 +31,15 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OCA\Backup\AppInfo\Application; use OCA\Backup\Db\PointRequest; use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\IRemoteRequest; use OCA\Backup\Model\RemoteInstance; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -49,8 +49,8 @@ use OCP\Files\NotPermittedException; * @package OCA\Backup\RemoteRequest */ class GetRestoringPoint extends CoreRequest implements IRemoteRequest { - use TNC23Logger; - use TNC23Deserialize; + use TDeserialize; + use TNCLogger; /** @var PointRequest */ diff --git a/lib/RemoteRequest/ListRestoringPoint.php b/lib/RemoteRequest/ListRestoringPoint.php index 07db537..cb0d7fb 100644 --- a/lib/RemoteRequest/ListRestoringPoint.php +++ b/lib/RemoteRequest/ListRestoringPoint.php @@ -31,12 +31,12 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OCA\Backup\AppInfo\Application; use OCA\Backup\Db\PointRequest; use OCA\Backup\IRemoteRequest; use OCA\Backup\Model\RemoteInstance; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TNCLogger; /** * Class ListRestoringPoint @@ -44,7 +44,7 @@ use OCA\Backup\Model\RemoteInstance; * @package OCA\Backup\RemoteRequest */ class ListRestoringPoint extends CoreRequest implements IRemoteRequest { - use TNC23Logger; + use TNCLogger; /** @var PointRequest */ diff --git a/lib/RemoteRequest/UpdateRestoringPoint.php b/lib/RemoteRequest/UpdateRestoringPoint.php index 92e9e63..26da79a 100644 --- a/lib/RemoteRequest/UpdateRestoringPoint.php +++ b/lib/RemoteRequest/UpdateRestoringPoint.php @@ -31,11 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OCA\Backup\AppInfo\Application; use OCA\Backup\Db\PointRequest; use OCA\Backup\Exceptions\RestoringPointNotFoundException; @@ -43,6 +38,11 @@ use OCA\Backup\IRemoteRequest; use OCA\Backup\Model\RemoteInstance; use OCA\Backup\Model\RestoringPoint; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -52,8 +52,8 @@ use OCP\Files\NotPermittedException; * @package OCA\Backup\RemoteRequest */ class UpdateRestoringPoint extends CoreRequest implements IRemoteRequest { - use TNC23Logger; - use TNC23Deserialize; + use TDeserialize; + use TNCLogger; /** @var PointRequest */ diff --git a/lib/RemoteRequest/UploadRestoringChunk.php b/lib/RemoteRequest/UploadRestoringChunk.php index 1b594c7..99f98ce 100644 --- a/lib/RemoteRequest/UploadRestoringChunk.php +++ b/lib/RemoteRequest/UploadRestoringChunk.php @@ -31,10 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\RemoteRequest; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\IDeserializable; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; use OCA\Backup\AppInfo\Application; use OCA\Backup\Exceptions\RestoringChunkNotFoundException; use OCA\Backup\Exceptions\RestoringPointNotFoundException; @@ -44,6 +40,10 @@ use OCA\Backup\Model\RestoringChunkPart; use OCA\Backup\Service\ChunkService; use OCA\Backup\Service\PackService; use OCA\Backup\Service\PointService; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; @@ -53,8 +53,8 @@ use OCP\Files\NotPermittedException; * @package OCA\Backup\RemoteRequest */ class UploadRestoringChunk extends CoreRequest implements IRemoteRequest { - use TNC23Deserialize; - use TNC23Logger; + use TDeserialize; + use TNCLogger; /** @var PointService */ diff --git a/lib/Service/ChunkService.php b/lib/Service/ChunkService.php index abb8780..8d9c008 100644 --- a/lib/Service/ChunkService.php +++ b/lib/Service/ChunkService.php @@ -31,10 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TFileTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use Exception; use OCA\Backup\Exceptions\ArchiveCreateException; use OCA\Backup\Exceptions\ArchiveFileNotFoundException; @@ -50,6 +46,10 @@ use OCA\Backup\Model\ArchiveFile; use OCA\Backup\Model\RestoringChunk; use OCA\Backup\Model\RestoringData; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TFileTools; +use OCA\Backup\Tools\Traits\TStringTools; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFile; @@ -67,7 +67,7 @@ class ChunkService { use TArrayTools; use TStringTools; use TFileTools; - use TNC23Deserialize; + use TDeserialize; public const BACKUP_SCRIPT = 'restore.php'; @@ -914,12 +914,12 @@ class ChunkService { try { return $this->getArchiveFileFromChunk($point, $chunk, $filename); } catch ( - ArchiveCreateException - | ArchiveNotFoundException - | ArchiveFileNotFoundException - | NotFoundException - | NotPermittedException $e) { - } + ArchiveCreateException + | ArchiveNotFoundException + | ArchiveFileNotFoundException + | NotFoundException + | NotPermittedException $e) { + } } throw new ArchiveFileNotFoundException(); diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index cd5a203..ea3443b 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -31,12 +31,12 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23Request; -use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use Exception; use OC; use OCA\Backup\AppInfo\Application; +use OCA\Backup\Tools\Model\NCRequest; +use OCA\Backup\Tools\Model\SimpleDataStore; +use OCA\Backup\Tools\Traits\TArrayTools; use OCA\Files_External\Service\GlobalStoragesService; use OCP\IConfig; @@ -319,10 +319,10 @@ class ConfigService { } /** - * @param NC23Request $request + * @param NCRequest $request * @param bool $longTimeout */ - public function configureRequest(NC23Request $request, bool $longTimeout = false): void { + public function configureRequest(NCRequest $request, bool $longTimeout = false): void { $request->setVerifyPeer($this->getAppValue(self::SELF_SIGNED_CERT) !== '1'); $request->setProtocols(['https', 'http']); $request->setHttpErrorsAllowed(true); diff --git a/lib/Service/CronService.php b/lib/Service/CronService.php index db940ab..2ddb8e8 100644 --- a/lib/Service/CronService.php +++ b/lib/Service/CronService.php @@ -31,9 +31,9 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OCA\Backup\Exceptions\JobsTimeSlotException; use OCA\Backup\Exceptions\SettingsException; +use OCA\Backup\Tools\Traits\TArrayTools; /** * Class CronService diff --git a/lib/Service/EncryptService.php b/lib/Service/EncryptService.php index 599faf9..95c2f28 100644 --- a/lib/Service/EncryptService.php +++ b/lib/Service/EncryptService.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use Exception; use OCA\Backup\Exceptions\EncryptionKeyException; use OCA\Backup\Exceptions\PackDecryptException; use OCA\Backup\Exceptions\PackEncryptException; +use OCA\Backup\Tools\Traits\TArrayTools; use SodiumException; /** diff --git a/lib/Service/ExportService.php b/lib/Service/ExportService.php index 27ccba6..5b6f1be 100644 --- a/lib/Service/ExportService.php +++ b/lib/Service/ExportService.php @@ -31,7 +31,7 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Exceptions\SignatoryException; use SodiumException; /** diff --git a/lib/Service/ExternalFolderService.php b/lib/Service/ExternalFolderService.php index d1607ea..bdbbd2d 100644 --- a/lib/Service/ExternalFolderService.php +++ b/lib/Service/ExternalFolderService.php @@ -31,14 +31,10 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use ArtificialOwl\MySmallPhpTools\Traits\TFileTools; use Exception; +use InvalidArgumentException; use OC; use OC\Files\Cache\Storage; -use OC\Files\FileInfo; use OC\Files\Node\File; use OC\Files\Node\Folder; use OCA\Backup\Db\ExternalFolderRequest; @@ -56,12 +52,17 @@ use OCA\Backup\Model\RestoringChunk; use OCA\Backup\Model\RestoringChunkPart; use OCA\Backup\Model\RestoringHealth; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TFileTools; +use OCA\Backup\Tools\Traits\TNCLogger; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCA\Files_External\Lib\StorageConfig; use OCA\Files_External\MountConfig; use OCA\Files_External\Service\GlobalStoragesService; use OCP\AppFramework\QueryException; use OCP\Files\Config\IUserMountCache; +use OCP\Files\FileInfo; use OCP\Files\GenericFileException; use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; @@ -76,8 +77,8 @@ use OCP\Lock\LockedException; * @package OCA\Backup\Service */ class ExternalFolderService { - use TNC23Deserialize; - use TNC23Logger; + use TDeserialize; + use TNCLogger; use TFileTools; @@ -172,14 +173,14 @@ class ExternalFolderService { try { $points[] = $this->getRestoringPoint($external, $node->getName()); } catch ( - ExternalFolderNotFoundException | - RestoringChunkPartNotFoundException | - RestoringPointException | - RestoringPointNotFoundException | - RestoringPointPackException | - GenericFileException | - NotPermittedException $e) { - } + ExternalFolderNotFoundException | + RestoringChunkPartNotFoundException | + RestoringPointException | + RestoringPointNotFoundException | + RestoringPointPackException | + GenericFileException | + NotPermittedException $e) { + } } return $points; @@ -224,11 +225,11 @@ class ExternalFolderService { return $point; } catch ( - InvalidItemException | - NotFoundException | - NotPermittedException | - LockedException $e) { - } + InvalidItemException | + NotFoundException | + NotPermittedException | + LockedException $e) { + } throw new RestoringPointNotFoundException(); } @@ -891,7 +892,7 @@ class ExternalFolderService { if ($objectStore) { $objectClass = $objectStore['class']; if (!is_subclass_of($objectClass, '\OCP\Files\ObjectStore\IObjectStore')) { - throw new \InvalidArgumentException('Invalid object store'); + throw new InvalidArgumentException('Invalid object store'); } $storage->setBackendOption('objectstore', new $objectClass($objectStore)); } diff --git a/lib/Service/FilesService.php b/lib/Service/FilesService.php index 0e284b7..f1f27d8 100644 --- a/lib/Service/FilesService.php +++ b/lib/Service/FilesService.php @@ -31,12 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TPathTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use OC; use OC\Files\Node\File; use OC\Files\Node\Folder; @@ -47,6 +41,11 @@ use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Model\ChangedFile; use OCA\Backup\Model\RestoringData; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; +use OCA\Backup\Tools\Traits\TStringTools; use OCP\Files\FileInfo; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; @@ -62,9 +61,8 @@ use OCP\Lock\LockedException; class FilesService { use TArrayTools; use TStringTools; - use TPathTools; - use TNC23Deserialize; - use TNC23Logger; + use TDeserialize; + use TNCLogger; public const APP_ROOT = __DIR__ . '/../../'; @@ -174,7 +172,7 @@ class FilesService { } if ($root !== '') { - $data->setRoot($this->withEndSlash($root)); + $data->setRoot(rtrim(str_replace('//', '/', $root), '/') . '/'); } } diff --git a/lib/Service/OccService.php b/lib/Service/OccService.php index f285fd8..9f4a83d 100644 --- a/lib/Service/OccService.php +++ b/lib/Service/OccService.php @@ -31,7 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; use OCA\Backup\Exceptions\MetadataException; use OCA\Backup\Exceptions\RemoteInstanceException; @@ -42,6 +41,7 @@ use OCA\Backup\Exceptions\RestoringPointException; use OCA\Backup\Exceptions\RestoringPointNotFoundException; use OCA\Backup\Exceptions\RestoringPointPackException; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Exceptions\SignatoryException; use OCP\Files\GenericFileException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; diff --git a/lib/Service/OutputService.php b/lib/Service/OutputService.php index ece023e..5cd1a9c 100644 --- a/lib/Service/OutputService.php +++ b/lib/Service/OutputService.php @@ -112,7 +112,7 @@ class OutputService { $file = $appDataRootWrapper->getNode('/' . $point->getId() . '/' . $point->getId() . '.log'); } catch (NotFoundException $e) { try { - $file = $appDataRootWrapper->newFile('/' . $point->getId() . '/' . $point->getId() . '.log', ''); + $file = $appDataRootWrapper->newFile('/' . $point->getId() . '/' . $point->getId() . '.log'); $new = true; } catch (NotPermittedException $e) { return; diff --git a/lib/Service/PackService.php b/lib/Service/PackService.php index de08f7e..1b940ce 100644 --- a/lib/Service/PackService.php +++ b/lib/Service/PackService.php @@ -31,10 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use ArtificialOwl\MySmallPhpTools\Traits\TFileTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use Exception; use OCA\Backup\Db\PointRequest; use OCA\Backup\Exceptions\ArchiveNotFoundException; @@ -52,6 +48,10 @@ use OCA\Backup\Model\RestoringChunk; use OCA\Backup\Model\RestoringChunkPart; use OCA\Backup\Model\RestoringData; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Traits\TFileTools; +use OCA\Backup\Tools\Traits\TNCLogger; +use OCA\Backup\Tools\Traits\TStringTools; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFile; @@ -67,7 +67,7 @@ use ZipArchive; */ class PackService { use TStringTools; - use TNC23Logger; + use TNCLogger; use TFileTools; diff --git a/lib/Service/PointService.php b/lib/Service/PointService.php index 27e8cc8..af57e19 100644 --- a/lib/Service/PointService.php +++ b/lib/Service/PointService.php @@ -31,13 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Signatory; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use Exception; use OC; use OC\Files\AppData\Factory; @@ -68,6 +61,13 @@ use OCA\Backup\Model\RestoringHealth; use OCA\Backup\Model\RestoringPoint; use OCA\Backup\SqlDump\SqlDumpMySQL; use OCA\Backup\SqlDump\SqlDumpPgSQL; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Exceptions\SignatureException; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; +use OCA\Backup\Tools\Traits\TNCSignatory; +use OCA\Backup\Tools\Traits\TStringTools; use OCA\Backup\Wrappers\AppDataRootWrapper; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCP\Files\NotFoundException; @@ -83,10 +83,10 @@ use Throwable; * @package OCA\Backup\Service */ class PointService { - use TNC23Signatory; - use TNC23Logger; + use TNCSignatory; + use TNCLogger; use TStringTools; - use TNC23Deserialize; + use TDeserialize; public const NOBACKUP_FILE = '.nobackup'; diff --git a/lib/Service/RemoteService.php b/lib/Service/RemoteService.php index 7283849..85a14ab 100644 --- a/lib/Service/RemoteService.php +++ b/lib/Service/RemoteService.php @@ -31,11 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Model\Request; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Logger; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; use Exception; use OCA\Backup\AppInfo\Application; use OCA\Backup\Db\RemoteRequest; @@ -50,6 +45,11 @@ use OCA\Backup\Model\RestoringChunk; use OCA\Backup\Model\RestoringChunkPart; use OCA\Backup\Model\RestoringHealth; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Model\Request; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLogger; /** * Class RemoteService @@ -57,8 +57,8 @@ use OCA\Backup\Model\RestoringPoint; * @package OCA\Backup\Service */ class RemoteService { - use TNC22Logger; - use TNC23Deserialize; + use TNCLogger; + use TDeserialize; /** @var RemoteRequest */ @@ -482,20 +482,20 @@ class RemoteService { $this->o(' ! <error>check configuration on remote instance</error>'); throw $e; } catch ( - RemoteInstanceNotFoundException - | RemoteResourceNotFoundException $e) { - $this->o(' ! <error>cannot communicate with remote instance</error>'); - throw $e; - } catch (RestoringPointNotFoundException $e) { - $this->o(' > <comment>restoring point not found</comment>'); - try { - $stored = $this->createPoint($remote, $point); - $this->o(' > restoring point created'); - } catch (Exception $e) { - $this->o(' ! <error>cannot create restoring point</error>'); + RemoteInstanceNotFoundException + | RemoteResourceNotFoundException $e) { + $this->o(' ! <error>cannot communicate with remote instance</error>'); throw $e; + } catch (RestoringPointNotFoundException $e) { + $this->o(' > <comment>restoring point not found</comment>'); + try { + $stored = $this->createPoint($remote, $point); + $this->o(' > restoring point created'); + } catch (Exception $e) { + $this->o(' ! <error>cannot create restoring point</error>'); + throw $e; + } } - } return $stored; } diff --git a/lib/Service/RemoteStreamService.php b/lib/Service/RemoteStreamService.php index 2dcd3f4..38dd732 100644 --- a/lib/Service/RemoteStreamService.php +++ b/lib/Service/RemoteStreamService.php @@ -7,7 +7,7 @@ declare(strict_types=1); * Nextcloud - Backup now. Restore later. * * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. + * later. See the COPYING file.s * * @author Maxence Lange <maxence@artificial-owl.com> * @copyright 2021, Maxence Lange <maxence@artificial-owl.com> @@ -31,20 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\ActivityPub\Nextcloud\nc23\NC23Signature; -use ArtificialOwl\MySmallPhpTools\Exceptions\RequestNetworkException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatureException; -use ArtificialOwl\MySmallPhpTools\Exceptions\WellKnownLinkNotFoundException; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23Request; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23Signatory; -use ArtificialOwl\MySmallPhpTools\Model\Nextcloud\nc23\NC23SignedRequest; -use ArtificialOwl\MySmallPhpTools\Model\Request; -use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23LocalSignatory; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23WellKnown; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use JsonSerializable; use OCA\Backup\AppInfo\Application; use OCA\Backup\Db\RemoteRequest; @@ -53,6 +39,20 @@ use OCA\Backup\Exceptions\RemoteInstanceNotFoundException; use OCA\Backup\Exceptions\RemoteResourceNotFoundException; use OCA\Backup\Model\RemoteInstance; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\ActivityPub\NCSignature; +use OCA\Backup\Tools\Exceptions\RequestNetworkException; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Exceptions\SignatureException; +use OCA\Backup\Tools\Exceptions\WellKnownLinkNotFoundException; +use OCA\Backup\Tools\Model\NCRequest; +use OCA\Backup\Tools\Model\NCSignatory; +use OCA\Backup\Tools\Model\NCSignedRequest; +use OCA\Backup\Tools\Model\Request; +use OCA\Backup\Tools\Model\SimpleDataStore; +use OCA\Backup\Tools\Traits\TDeserialize; +use OCA\Backup\Tools\Traits\TNCLocalSignatory; +use OCA\Backup\Tools\Traits\TNCWellKnown; +use OCA\Backup\Tools\Traits\TStringTools; use OCP\AppFramework\Http; use OCP\IURLGenerator; @@ -61,11 +61,11 @@ use OCP\IURLGenerator; * * @package OCA\Backup\Service */ -class RemoteStreamService extends NC23Signature { - use TNC23Deserialize; - use TNC23LocalSignatory; +class RemoteStreamService extends NCSignature { + use TDeserialize; + use TNCLocalSignatory; use TStringTools; - use TNC23WellKnown; + use TNCWellKnown; /** @var IURLGenerator */ @@ -213,14 +213,14 @@ class RemoteStreamService extends NC23Signature { * @param string $keyId * @param bool $refresh * - * @return NC23Signatory + * @return NCSignatory * @throws SignatoryException * @throws SignatureException */ - public function retrieveSignatory(string $keyId, bool $refresh = true): NC23Signatory { + public function retrieveSignatory(string $keyId, bool $refresh = true): NCSignatory { if (!$refresh) { try { - return $this->remoteRequest->getFromHref(NC23Signatory::removeFragment($keyId)); + return $this->remoteRequest->getFromHref(NCSignatory::removeFragment($keyId)); } catch (RemoteInstanceNotFoundException $e) { throw new SignatoryException(); } @@ -229,7 +229,7 @@ class RemoteStreamService extends NC23Signature { $remoteInstance = new RemoteInstance($keyId); $confirm = $this->uuid(); - $request = new NC23Request(); + $request = new NCRequest(); $this->configService->configureRequest($request); $this->downloadSignatory($remoteInstance, $keyId, ['auth' => $confirm], $request); @@ -294,7 +294,7 @@ class RemoteStreamService extends NC23Signature { * @param array $params * @param bool $longTimeout * - * @return NC23SignedRequest + * @return NCSignedRequest * @throws RemoteInstanceException * @throws RemoteInstanceNotFoundException * @throws RemoteResourceNotFoundException @@ -306,8 +306,8 @@ class RemoteStreamService extends NC23Signature { ?JsonSerializable $object = null, array $params = [], bool $longTimeout = false - ): NC23SignedRequest { - $request = new NC23Request('', $type); + ): NCSignedRequest { + $request = new NCRequest('', $type); $this->configService->configureRequest($request, $longTimeout); $link = $this->getRemoteInstanceEntry($instance, $item, $params); $request->basedOnUrl($link); diff --git a/lib/Service/RestoreService.php b/lib/Service/RestoreService.php index cd00290..8ed5bb5 100644 --- a/lib/Service/RestoreService.php +++ b/lib/Service/RestoreService.php @@ -31,9 +31,6 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; -use ArtificialOwl\MySmallPhpTools\Traits\TFileTools; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; use DateTime; use Exception; use OC\Files\Node\File; @@ -46,6 +43,9 @@ use OCA\Backup\Model\RestoringChunk; use OCA\Backup\Model\RestoringChunkPart; use OCA\Backup\Model\RestoringData; use OCA\Backup\Model\RestoringPoint; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCA\Backup\Tools\Traits\TFileTools; +use OCA\Backup\Tools\Traits\TStringTools; use OCP\Files\FileInfo; use OCP\Files\GenericFileException; use OCP\Files\InvalidPathException; diff --git a/lib/Service/UploadService.php b/lib/Service/UploadService.php index 7d12d44..5ec1cf0 100644 --- a/lib/Service/UploadService.php +++ b/lib/Service/UploadService.php @@ -31,8 +31,8 @@ declare(strict_types=1); namespace OCA\Backup\Service; -use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger; -use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; +use OCA\Backup\Tools\Traits\TNCLogger; +use OCA\Backup\Tools\Traits\TStringTools; use Exception; use OCA\Backup\AppInfo\Application; use OCA\Backup\Exceptions\ExternalFolderNotFoundException; @@ -63,7 +63,7 @@ use OCP\Lock\LockedException; */ class UploadService { use TStringTools; - use TNC23Logger; + use TNCLogger; @@ -280,14 +280,14 @@ class UploadService { $this->remoteService->uploadPart($instance, $point, $chunk, $part); $this->o('<info>ok</info>'); } catch ( - RestoringChunkNotFoundException - | RemoteInstanceException - | RemoteInstanceNotFoundException - | RestoringChunkPartNotFoundException - | RestoringPointNotInitiatedException - | RemoteResourceNotFoundException $e) { - $this->o('<error>' . get_class($e) . $e->getMessage() . '</error>'); - } + RestoringChunkNotFoundException + | RemoteInstanceException + | RemoteInstanceNotFoundException + | RestoringChunkPartNotFoundException + | RestoringPointNotInitiatedException + | RemoteResourceNotFoundException $e) { + $this->o('<error>' . get_class($e) . $e->getMessage() . '</error>'); + } } } @@ -417,16 +417,16 @@ class UploadService { $this->externalFolderService->uploadPart($external, $point, $health, $chunk, $part); $this->o('<info>ok</info>'); } catch ( - RestoringChunkNotFoundException | - RestoringPointNotInitiatedException | - RestoringPointException | - RestoringPointNotFoundException | - ExternalFolderNotFoundException | - GenericFileException | - NotPermittedException | - LockedException $e) { - $this->o('<error>' . get_class($e) . ' ' . $e->getMessage() . '</error>'); - } + RestoringChunkNotFoundException | + RestoringPointNotInitiatedException | + RestoringPointException | + RestoringPointNotFoundException | + ExternalFolderNotFoundException | + GenericFileException | + NotPermittedException | + LockedException $e) { + $this->o('<error>' . get_class($e) . ' ' . $e->getMessage() . '</error>'); + } } } diff --git a/lib/SqlDump/SqlDumpMySQL.php b/lib/SqlDump/SqlDumpMySQL.php index 6781c3c..f2e4c37 100644 --- a/lib/SqlDump/SqlDumpMySQL.php +++ b/lib/SqlDump/SqlDumpMySQL.php @@ -31,12 +31,12 @@ declare(strict_types=1); namespace OCA\Backup\SqlDump; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use Ifsnop\Mysqldump\Mysqldump; use OCA\Backup\Exceptions\SqlDumpException; use OCA\Backup\Exceptions\SqlParamsException; use OCA\Backup\ISqlDump; use OCA\Backup\Service\ConfigService; +use OCA\Backup\Tools\Traits\TArrayTools; use Throwable; /** diff --git a/lib/SqlDump/SqlDumpPgSQL.php b/lib/SqlDump/SqlDumpPgSQL.php index 4464c2b..2011de3 100644 --- a/lib/SqlDump/SqlDumpPgSQL.php +++ b/lib/SqlDump/SqlDumpPgSQL.php @@ -31,10 +31,10 @@ declare(strict_types=1); namespace OCA\Backup\SqlDump; -use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; use OCA\Backup\Exceptions\SqlDumpException; use OCA\Backup\Exceptions\SqlParamsException; use OCA\Backup\ISqlDump; +use OCA\Backup\Tools\Traits\TArrayTools; use Spatie\DbDumper\Databases\PostgreSql; use Throwable; diff --git a/lib/Tools/ActivityPub/NCSignature.php b/lib/Tools/ActivityPub/NCSignature.php new file mode 100644 index 0000000..a6a4bf0 --- /dev/null +++ b/lib/Tools/ActivityPub/NCSignature.php @@ -0,0 +1,413 @@ +<?php +/* + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2017 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\ActivityPub; + +use DateTime; +use Exception; +use OC; +use OCA\Backup\Tools\Exceptions\InvalidOriginException; +use OCA\Backup\Tools\Exceptions\ItemNotFoundException; +use OCA\Backup\Tools\Exceptions\MalformedArrayException; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Exceptions\SignatureException; +use OCA\Backup\Tools\Model\NCRequest; +use OCA\Backup\Tools\Model\NCSignatory; +use OCA\Backup\Tools\Model\NCSignedRequest; +use OCA\Backup\Tools\Model\SimpleDataStore; +use OCA\Backup\Tools\Traits\TNCSignatory; +use OCP\IRequest; + +class NCSignature { + public const DATE_HEADER = 'D, d M Y H:i:s T'; + public const DATE_OBJECT = 'Y-m-d\TH:i:s\Z'; + + public const DATE_TTL = 300; + + + use TNCSignatory; + + + /** @var int */ + private $ttl = self::DATE_TTL; + private $dateHeader = self::DATE_HEADER; + + + /** + * @param string $body + * + * @return NCSignedRequest + * @throws InvalidOriginException + * @throws MalformedArrayException + * @throws SignatoryException + * @throws SignatureException + */ + public function incomingSignedRequest(string $body = ''): NCSignedRequest { + if ($body === '') { + $body = file_get_contents('php://input'); + } + + $this->debug('[<<] incoming', ['body' => $body]); + + $signedRequest = new NCSignedRequest($body); + $signedRequest->setIncomingRequest(OC::$server->get(IRequest::class)); + + $this->verifyIncomingRequestTime($signedRequest); + $this->verifyIncomingRequestContent($signedRequest); + $this->setIncomingSignatureHeader($signedRequest); + $this->setIncomingClearSignature($signedRequest); + $this->parseIncomingSignatureHeader($signedRequest); + $this->verifyIncomingRequestSignature($signedRequest); + + return $signedRequest; + } + + + /** + * @param NCRequest $request + * @param NCSignatory $signatory + * + * @return NCSignedRequest + * @throws SignatoryException + */ + public function signOutgoingRequest(NCRequest $request, NCSignatory $signatory): NCSignedRequest { + $signedRequest = new NCSignedRequest($request->getDataBody()); + $signedRequest->setOutgoingRequest($request) + ->setSignatory($signatory); + + $this->setOutgoingSignatureHeader($signedRequest); + $this->setOutgoingClearSignature($signedRequest); + $this->setOutgoingSignedSignature($signedRequest); + $this->signingOutgoingRequest($signedRequest); + + return $signedRequest; + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @throws SignatureException + */ + private function verifyIncomingRequestTime(NCSignedRequest $signedRequest): void { + $request = $signedRequest->getIncomingRequest(); + + try { + $dTime = new DateTime($request->getHeader('date')); + $signedRequest->setTime($dTime->getTimestamp()); + } catch (Exception $e) { + $this->e($e, ['header' => $request->getHeader('date')]); + throw new SignatureException('datetime exception'); + } + + if ($signedRequest->getTime() < (time() - $this->ttl)) { + throw new SignatureException('object is too old'); + } + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @throws SignatureException + */ + private function verifyIncomingRequestContent(NCSignedRequest $signedRequest): void { + $request = $signedRequest->getIncomingRequest(); + + if (strlen($signedRequest->getBody()) !== (int)$request->getHeader('content-length')) { + throw new SignatureException('issue with content-length'); + } + + if ($request->getHeader('digest') !== '' + && $signedRequest->getDigest() !== $request->getHeader('digest')) { + throw new SignatureException('issue with digest'); + } + } + + /** + * @param NCSignedRequest $signedRequest + */ + private function setIncomingSignatureHeader(NCSignedRequest $signedRequest): void { + $sign = []; + $request = $signedRequest->getIncomingRequest(); + foreach (explode(',', $request->getHeader('Signature')) as $entry) { + if ($entry === '' || !strpos($entry, '=')) { + continue; + } + + [$k, $v] = explode('=', $entry, 2); + preg_match('/"([^"]+)"/', $v, $varr); + if ($varr[0] !== null) { + $v = trim($varr[0], '"'); + } + $sign[$k] = $v; + } + + $signedRequest->setSignatureHeader(new SimpleDataStore($sign)); + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @throws SignatureException + */ + private function setIncomingClearSignature(NCSignedRequest $signedRequest): void { + $request = $signedRequest->getIncomingRequest(); + $headers = explode(' ', $signedRequest->getSignatureHeader()->g('headers')); + + $enforceHeaders = array_merge( + ['content-length', 'date', 'host'], + $this->setupArray('enforceSignatureHeaders') + ); + if (!empty(array_diff($enforceHeaders, $headers))) { + throw new SignatureException('missing elements in \'headers\''); + } + + $target = strtolower($request->getMethod()) . " " . $request->getRequestUri(); + $estimated = ['(request-target): ' . $target]; + + foreach ($headers as $key) { + $value = $request->getHeader($key); + if (strtolower($key) === 'host') { + $value = $signedRequest->getIncomingRequest()->getServerHost(); + } + if ($value === '') { + throw new SignatureException('empty elements in \'headers\''); + } + + $estimated[] = $key . ': ' . $value; + } + $signedRequest->setClearSignature(implode("\n", $estimated)); + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @throws MalformedArrayException + * @throws InvalidOriginException + */ + private function parseIncomingSignatureHeader(NCSignedRequest $signedRequest): void { + $data = $signedRequest->getSignatureHeader(); + $data->hasKeys(['keyId', 'headers', 'signature'], true); + + $signedRequest->setOrigin($this->getKeyOrigin($data->g('keyId'))); + $signedRequest->setSignedSignature($data->g('signature')); + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @throws SignatoryException + * @throws SignatureException + */ + private function verifyIncomingRequestSignature(NCSignedRequest $signedRequest) { + $data = $signedRequest->getSignatureHeader(); + + try { + $signedRequest->setSignatory($this->retrieveSignatory($data->g('keyId'), false)); + $this->verifySignedRequest($signedRequest); + } catch (SignatoryException $e) { + $signedRequest->setSignatory($this->retrieveSignatory($data->g('keyId'), true)); + $this->verifySignedRequest($signedRequest); + } + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @throws SignatureException + */ + private function verifySignedRequest(NCSignedRequest $signedRequest) { + $publicKey = $signedRequest->getSignatory()->getPublicKey(); + if ($publicKey === '') { + throw new SignatureException('empty public key'); + } + + try { + $this->verifyString( + $signedRequest->getClearSignature(), + base64_decode($signedRequest->getSignedSignature()), + $publicKey, + $this->getUsedEncryption($signedRequest) + ); + } catch (SignatureException $e) { + $this->debug('signature issue', ['signed' => $signedRequest]); + throw $e; + } + } + + + /** + * @param NCSignedRequest $signedRequest + */ + private function setOutgoingSignatureHeader(NCSignedRequest $signedRequest): void { + $request = $signedRequest->getOutgoingRequest(); + + $data = new SimpleDataStore(); + $data->s('(request-target)', NCRequest::method($request->getType()) . ' ' . $request->getPath()) + ->sInt('content-length', strlen($signedRequest->getBody())) + ->s('date', gmdate($this->dateHeader)) + ->s('digest', $signedRequest->getDigest()) + ->s('host', $request->getHost()); + + $signedRequest->setSignatureHeader($data); + } + + + /** + * @param NCSignedRequest $signedRequest + */ + private function setOutgoingClearSignature(NCSignedRequest $signedRequest): void { + $signing = []; + $data = $signedRequest->getSignatureHeader(); + foreach ($data->keys() as $element) { + try { + $value = $data->gItem($element); + $signing[] = $element . ': ' . $value; + if ($element !== '(request-target)') { + $signedRequest->getOutgoingRequest()->addHeader($element, $value); + } + } catch (ItemNotFoundException $e) { + } + } + + $signedRequest->setClearSignature(implode("\n", $signing)); + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @throws SignatoryException + */ + private function setOutgoingSignedSignature(NCSignedRequest $signedRequest): void { + $clear = $signedRequest->getClearSignature(); + $signed = $this->signString($clear, $signedRequest->getSignatory()); + $signedRequest->setSignedSignature($signed); + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @return void + */ + private function signingOutgoingRequest(NCSignedRequest $signedRequest): void { + $headers = array_diff($signedRequest->getSignatureHeader()->keys(), ['(request-target)']); + $signatory = $signedRequest->getSignatory(); + $signatureElements = [ + 'keyId="' . $signatory->getKeyId() . '"', + 'algorithm="' . $this->getChosenEncryption($signatory) . '"', + 'headers="' . implode(' ', $headers) . '"', + 'signature="' . $signedRequest->getSignedSignature() . '"' + ]; + + $signedRequest->getOutgoingRequest()->addHeader('Signature', implode(',', $signatureElements)); + } + + + /** + * @param NCSignedRequest $signedRequest + * + * @return string + */ + private function getUsedEncryption(NCSignedRequest $signedRequest): string { + switch ($signedRequest->getSignatureHeader()->g('algorithm')) { + case 'rsa-sha512': + return NCSignatory::SHA512; + + case 'rsa-sha256': + default: + return NCSignatory::SHA256; + } + } + + /** + * @param NCSignatory $signatory + * + * @return string + */ + private function getChosenEncryption(NCSignatory $signatory): string { + switch ($signatory->getAlgorithm()) { + case NCSignatory::SHA512: + return 'ras-sha512'; + + case NCSignatory::SHA256: + default: + return 'ras-sha256'; + } + } + + + /** + * @param NCSignatory $signatory + * + * @return int + */ + public function getOpenSSLAlgo(NCSignatory $signatory): int { + switch ($signatory->getAlgorithm()) { + case NCSignatory::SHA512: + return OPENSSL_ALGO_SHA512; + + case NCSignatory::SHA256: + default: + return OPENSSL_ALGO_SHA256; + } + } +} diff --git a/lib/Tools/Db/ExtendedQueryBuilder.php b/lib/Tools/Db/ExtendedQueryBuilder.php new file mode 100644 index 0000000..f36da94 --- /dev/null +++ b/lib/Tools/Db/ExtendedQueryBuilder.php @@ -0,0 +1,1135 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Db; + +use DateInterval; +use DateTime; +use Doctrine\DBAL\Query\QueryBuilder as DBALQueryBuilder; +use Exception; +use OC; +use OC\DB\QueryBuilder\QueryBuilder; +use OC\SystemConfig; +use OCA\Backup\Tools\Exceptions\DateTimeException; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\RowNotFoundException; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCP\DB\QueryBuilder\ICompositeExpression; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use Psr\Log\LoggerInterface; + +class ExtendedQueryBuilder extends QueryBuilder { + use TArrayTools; + + + /** @var string */ + private $defaultSelectAlias = ''; + + /** @var array */ + private $defaultValues = []; + + + public function __construct() { + parent::__construct( + OC::$server->get(IDBConnection::class), + OC::$server->get(SystemConfig::class), + OC::$server->get(LoggerInterface::class) + ); + } + + + /** + * @param string $alias + * + * @return self + */ + public function setDefaultSelectAlias(string $alias): self { + $this->defaultSelectAlias = $alias; + + return $this; + } + + /** + * @return string + */ + public function getDefaultSelectAlias(): string { + return $this->defaultSelectAlias; + } + + + /** + * @return array + */ + public function getDefaultValues(): array { + return $this->defaultValues; + } + + /** + * @param string $key + * @param string $value + * + * @return $this + */ + public function addDefaultValue(string $key, string $value): self { + $this->defaultValues[$key] = $value; + + return $this; + } + + /** + * @param int $size + * @param int $page + */ + public function paginate(int $size, int $page = 0): void { + if ($page < 0) { + $page = 0; + } + + $this->chunk($page * $size, $size); + } + + /** + * @param int $offset + * @param int $limit + */ + public function chunk(int $offset, int $limit): void { + if ($offset > -1) { + $this->setFirstResult($offset); + } + + if ($limit > 0) { + $this->setMaxResults($limit); + } + } + + + /** + * Limit the request to the Id + * + * @param int $id + */ + public function limitToId(int $id): void { + $this->limitInt('id', $id); + } + + /** + * @param array $ids + */ + public function limitToIds(array $ids): void { + $this->limitArray('id', $ids); + } + + /** + * @param string $id + */ + public function limitToIdString(string $id): void { + $this->limit('id', $id); + } + + /** + * @param string $userId + */ + public function limitToUserId(string $userId): void { + $this->limit('user_id', $userId); + } + + /** + * @param string $uniqueId + */ + public function limitToUniqueId(string $uniqueId): void { + $this->limit('unique_id', $uniqueId); + } + + /** + * @param string $memberId + */ + public function limitToMemberId(string $memberId): void { + $this->limit('member_id', $memberId); + } + + /** + * @param string $status + */ + public function limitToStatus(string $status): void { + $this->limit('status', $status, '', false); + } + + /** + * @param int $type + */ + public function limitToType(int $type): void { + $this->limitInt('type', $type); + } + + /** + * @param string $type + */ + public function limitToTypeString(string $type): void { + $this->limit('type', $type, '', false); + } + + /** + * @param string $token + */ + public function limitToToken(string $token): void { + $this->limit('token', $token); + } + + + /** + * Limit the request to the creation + * + * @param int $delay + * + * @return self + * @throws Exception + */ + public function limitToCreation(int $delay = 0): self { + $date = new DateTime('now'); + $date->sub(new DateInterval('PT' . $delay . 'M')); + + $this->limitToDBFieldDateTime('creation', $date, true); + + return $this; + } + + + /** + * @param string $field + * @param DateTime $date + * @param bool $orNull + */ + public function limitToDBFieldDateTime(string $field, DateTime $date, bool $orNull = false): void { + $expr = $this->expr(); + $pf = ($this->getType() === DBALQueryBuilder::SELECT) ? $this->getDefaultSelectAlias() + . '.' : ''; + $field = $pf . $field; + + $orX = $expr->orX(); + $orX->add( + $expr->lte($field, $this->createNamedParameter($date, IQueryBuilder::PARAM_DATE)) + ); + + if ($orNull === true) { + $orX->add($expr->isNull($field)); + } + + $this->andWhere($orX); + } + + + /** + * @param int $timestamp + * @param string $field + * + * @throws DateTimeException + */ + public function limitToSince(int $timestamp, string $field): void { + try { + $dTime = new DateTime(); + $dTime->setTimestamp($timestamp); + } catch (Exception $e) { + throw new DateTimeException($e->getMessage()); + } + + $expr = $this->expr(); + $pf = ($this->getType() === DBALQueryBuilder::SELECT) ? $this->getDefaultSelectAlias() . '.' : ''; + $field = $pf . $field; + + $orX = $expr->orX(); + $orX->add( + $expr->gte($field, $this->createNamedParameter($dTime, IQueryBuilder::PARAM_DATE)) + ); + + $this->andWhere($orX); + } + + + /** + * @param string $field + * @param string $value + */ + public function searchInDBField(string $field, string $value): void { + $expr = $this->expr(); + + $pf = ($this->getType() === DBALQueryBuilder::SELECT) ? $this->getDefaultSelectAlias() . '.' : ''; + $field = $pf . $field; + + $this->andWhere($expr->iLike($field, $this->createNamedParameter($value))); + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + */ + public function like(string $field, string $value, string $alias = '', bool $cs = true): void { + $this->andWhere($this->exprLike($field, $value, $alias, $cs)); + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + */ + public function limit(string $field, string $value, string $alias = '', bool $cs = true): void { + $this->andWhere($this->exprLimit($field, $value, $alias, $cs)); + } + + /** + * @param string $field + * @param int $value + * @param string $alias + */ + public function limitInt(string $field, int $value, string $alias = ''): void { + $this->andWhere($this->exprLimitInt($field, $value, $alias)); + } + + /** + * @param string $field + * @param bool $value + * @param string $alias + */ + public function limitBool(string $field, bool $value, string $alias = ''): void { + $this->andWhere($this->exprLimitBool($field, $value, $alias)); + } + + /** + * @param string $field + * @param bool $orNull + * @param string $alias + */ + public function limitEmpty(string $field, bool $orNull = false, string $alias = ''): void { + $this->andWhere($this->exprLimitEmpty($field, $orNull, $alias)); + } + + /** + * @param string $field + * @param bool $orEmpty + * @param string $alias + */ + public function limitNull(string $field, bool $orEmpty = false, string $alias = ''): void { + $this->andWhere($this->exprLimitNull($field, $orEmpty, $alias)); + } + + /** + * @param string $field + * @param array $value + * @param string $alias + * @param bool $cs + */ + public function limitArray(string $field, array $value, string $alias = '', bool $cs = true): void { + $this->andWhere($this->exprLimitArray($field, $value, $alias, $cs)); + } + + /** + * @param string $field + * @param array $value + * @param string $alias + */ + public function limitInArray(string $field, array $value, string $alias = ''): void { + $this->andWhere($this->exprLimitInArray($field, $value, $alias)); + } + + /** + * @param string $field + * @param int $flag + * @param string $alias + */ + public function limitBitwise(string $field, int $flag, string $alias = ''): void { + $this->andWhere($this->exprLimitBitwise($field, $flag, $alias)); + } + + /** + * @param string $field + * @param int $value + * @param bool $gte + * @param string $alias + */ + public function gt(string $field, int $value, bool $gte = false, string $alias = ''): void { + $this->andWhere($this->exprGt($field, $value, $gte, $alias)); + } + + /** + * @param string $field + * @param int $value + * @param bool $lte + * @param string $alias + */ + public function lt(string $field, int $value, bool $lte = false, string $alias = ''): void { + $this->andWhere($this->exprLt($field, $value, $lte, $alias)); + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + * + * @return string + */ + public function exprLike(string $field, string $value, string $alias = '', bool $cs = true): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + if ($cs) { + return (string) $expr->like($field, $this->createNamedParameter($value)); + } else { + return (string) $expr->iLike($field, $this->createNamedParameter($value)); + } + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + * + * @return string + */ + public function exprLimit(string $field, string $value, string $alias = '', bool $cs = true): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + if ($value === '') { + return (string) $expr->emptyString($field); + } + if ($cs) { + return (string) $expr->eq($field, $this->createNamedParameter($value)); + } else { + $func = $this->func(); + + return (string) $expr->eq($func->lower($field), $func->lower($this->createNamedParameter($value))); + } + } + + + /** + * @param string $field + * @param int $value + * @param string $alias + * + * @return string + */ + public function exprLimitInt(string $field, int $value, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->eq($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_INT)); + } + + + /** + * @param string $field + * @param bool $value + * @param string $alias + * + * @return string + */ + public function exprLimitBool(string $field, bool $value, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->eq($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_BOOL)); + } + + /** + * @param string $field + * @param bool $orNull + * @param string $alias + * + * @return ICompositeExpression + */ + public function exprLimitEmpty( + string $field, + bool $orNull = false, + string $alias = '' + ): ICompositeExpression { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + $orX = $expr->orX(); + $orX->add($expr->emptyString($field)); + if ($orNull) { + $orX->add($expr->isNull($field)); + } + + return $orX; + } + + /** + * @param string $field + * @param bool $orEmpty + * @param string $alias + * + * @return ICompositeExpression + */ + public function exprLimitNull( + string $field, + bool $orEmpty = false, + string $alias = '' + ): ICompositeExpression { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + $orX = $expr->orX(); + $orX->add($expr->isNull($field)); + if ($orEmpty) { + $orX->add($expr->emptyString($field)); + } + + return $orX; + } + + + /** + * @param string $field + * @param array $values + * @param string $alias + * @param bool $cs + * + * @return ICompositeExpression + */ + public function exprLimitArray( + string $field, + array $values, + string $alias = '', + bool $cs = true + ): ICompositeExpression { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $andX = $this->expr()->andX(); + foreach ($values as $value) { + if (is_integer($value)) { + $andX->add($this->exprLimitInt($field, $value, $alias)); + } else { + $andX->add($this->exprLimit($field, $value, $alias, $cs)); + } + } + + return $andX; + } + + + /** + * @param string $field + * @param array $values + * @param string $alias + * + * @return string + */ + public function exprLimitInArray(string $field, array $values, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->in($field, $this->createNamedParameter($values, IQueryBuilder::PARAM_STR_ARRAY)); + } + + + /** + * @param string $field + * @param int $flag + * @param string $alias + * + * @return string + */ + public function exprLimitBitwise(string $field, int $flag, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->gt( + $expr->bitwiseAnd($field, $flag), + $this->createNamedParameter(0, IQueryBuilder::PARAM_INT) + ); + } + + + /** + * @param string $field + * @param int $value + * @param bool $lte + * @param string $alias + * + * @return string + */ + public function exprLt(string $field, int $value, bool $lte = false, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + if ($lte) { + return (string) $expr->lte($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_INT)); + } else { + return (string) $expr->lt($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_INT)); + } + } + + /** + * @param string $field + * @param int $value + * @param bool $gte + * @param string $alias + * + * @return string + */ + public function exprGt(string $field, int $value, bool $gte = false, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + if ($gte) { + return (string) $expr->gte($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_INT)); + } else { + return (string) $expr->gt($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_INT)); + } + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + */ + public function unlike(string $field, string $value, string $alias = '', bool $cs = true): void { + $this->andWhere($this->exprUnlike($field, $value, $alias, $cs)); + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + */ + public function filter(string $field, string $value, string $alias = '', bool $cs = true): void { + $this->andWhere($this->exprFilter($field, $value, $alias, $cs)); + } + + /** + * @param string $field + * @param int $value + * @param string $alias + */ + public function filterInt(string $field, int $value, string $alias = ''): void { + $this->andWhere($this->exprFilterInt($field, $value, $alias)); + } + + /** + * @param string $field + * @param bool $value + * @param string $alias + */ + public function filterBool(string $field, bool $value, string $alias = ''): void { + $this->andWhere($this->exprFilterBool($field, $value, $alias)); + } + + /** + * @param string $field + * @param bool $norNull + * @param string $alias + */ + public function filterEmpty(string $field, bool $norNull = false, string $alias = ''): void { + $this->andWhere($this->exprFilterEmpty($field, $norNull, $alias)); + } + + /** + * @param string $field + * @param bool $norEmpty + * @param string $alias + */ + public function filterNull(string $field, bool $norEmpty = false, string $alias = ''): void { + $this->andWhere($this->exprFilterNull($field, $norEmpty, $alias)); + } + + /** + * @param string $field + * @param array $value + * @param string $alias + * @param bool $cs + */ + public function filterArray(string $field, array $value, string $alias = '', bool $cs = true): void { + $this->andWhere($this->exprFilterArray($field, $value, $alias, $cs)); + } + + /** + * @param string $field + * @param array $value + * @param string $alias + */ + public function filterInArray(string $field, array $value, string $alias = ''): void { + $this->andWhere($this->exprFilterInArray($field, $value, $alias)); + } + + /** + * @param string $field + * @param int $flag + * @param string $alias + */ + public function filterBitwise(string $field, int $flag, string $alias = ''): void { + $this->andWhere($this->exprFilterBitwise($field, $flag, $alias)); + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + * + * @return string + */ + public function exprUnlike(string $field, string $value, string $alias = '', bool $cs = true): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + if ($cs) { + return (string) $expr->notLike($field, $this->createNamedParameter($value)); + } else { + $func = $this->func(); + + return (string) $expr->notLike($func->lower($field), $func->lower($this->createNamedParameter($value))); + } + } + + + /** + * @param string $field + * @param string $value + * @param string $alias + * @param bool $cs + * + * @return string + */ + public function exprFilter(string $field, string $value, string $alias = '', bool $cs = true): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + if ($value === '') { + return (string) $expr->nonEmptyString($field); + } + if ($cs) { + return (string) $expr->neq($field, $this->createNamedParameter($value)); + } else { + $func = $this->func(); + + return (string) $expr->neq($func->lower($field), $func->lower($this->createNamedParameter($value))); + } + } + + + /** + * @param string $field + * @param int $value + * @param string $alias + * + * @return string + */ + public function exprFilterInt(string $field, int $value, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->neq($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_INT)); + } + + + /** + * @param string $field + * @param bool $value + * @param string $alias + * + * @return string + */ + public function exprFilterBool(string $field, bool $value, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->neq($field, $this->createNamedParameter($value, IQueryBuilder::PARAM_BOOL)); + } + + /** + * @param string $field + * @param bool $norNull + * @param string $alias + * + * @return ICompositeExpression + */ + public function exprFilterEmpty( + string $field, + bool $norNull = false, + string $alias = '' + ): ICompositeExpression { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + $andX = $expr->andX(); + $andX->add($expr->nonEmptyString($field)); + if ($norNull) { + $andX->add($expr->isNotNull($field)); + } + + return $andX; + } + + /** + * @param string $field + * @param bool $norEmpty + * @param string $alias + * + * @return ICompositeExpression + */ + public function exprFilterNull( + string $field, + bool $norEmpty = false, + string $alias = '' + ): ICompositeExpression { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + $andX = $expr->andX(); + $andX->add($expr->isNotNull($field)); + if ($norEmpty) { + $andX->add($expr->nonEmptyString($field)); + } + + return $andX; + } + + + /** + * @param string $field + * @param array $values + * @param string $alias + * @param bool $cs + * + * @return ICompositeExpression + */ + public function exprFilterArray( + string $field, + array $values, + string $alias = '', + bool $cs = true + ): ICompositeExpression { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $orX = $this->expr()->orX(); + foreach ($values as $value) { + if (is_integer($value)) { + $orX->add($this->exprFilterInt($field, $value, $alias)); + } else { + $orX->add($this->exprFilter($field, $value, $alias, $cs)); + } + } + + return $orX; + } + + + /** + * @param string $field + * @param array $values + * @param string $alias + * + * @return string + */ + public function exprFilterInArray(string $field, array $values, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->notIn($field, $this->createNamedParameter($values, IQueryBuilder::PARAM_STR_ARRAY)); + } + + + /** + * @param string $field + * @param int $flag + * @param string $alias + * + * @return string + */ + public function exprFilterBitwise(string $field, int $flag, string $alias = ''): string { + if ($this->getType() === DBALQueryBuilder::SELECT) { + $field = (($alias === '') ? $this->getDefaultSelectAlias() : $alias) . '.' . $field; + } + + $expr = $this->expr(); + + return (string) $expr->eq( + $expr->bitwiseAnd($field, $flag), + $this->createNamedParameter(0, IQueryBuilder::PARAM_INT) + ); + } + + + /** + * @param string $object + * @param array $params + * + * @return IQueryRow + * @throws RowNotFoundException + * @throws InvalidItemException + */ + public function asItem(string $object, array $params = []): IQueryRow { + return $this->getRow([$this, 'parseSimpleSelectSql'], $object, $params); + } + + /** + * @param string $object + * @param array $params + * + * @return IQueryRow[] + */ + public function asItems(string $object, array $params = []): array { + return $this->getRows([$this, 'parseSimpleSelectSql'], $object, $params); + } + + + /** + * @param string $field + * @param array $params + * + * @return IQueryRow + * @throws InvalidItemException + * @throws RowNotFoundException + */ + public function asItemFromField(string $field, array $params = []): IQueryRow { + $param['modelFromField'] = $field; + + return $this->getRow([$this, 'parseSimpleSelectSql'], '', $params); + } + + /** + * @param string $field + * @param array $params + * + * @return IQueryRow[] + */ + public function asItemsFromField(string $field, array $params = []): array { + $param['modelFromField'] = $field; + + return $this->getRows([$this, 'parseSimpleSelectSql'], $field, $params); + } + + + /** + * @param array $data + * @param ExtendedQueryBuilder $qb + * @param string $object + * @param array $params + * + * @return IQueryRow + * @throws InvalidItemException + */ + private function parseSimpleSelectSql( + array $data, + ExtendedQueryBuilder $qb, + string $object, + array $params + ): IQueryRow { + $fromField = $this->get('modelFromField', $params); + if ($fromField !== '') { + $object = $fromField; + } + + $item = new $object(); + if (!($item instanceof IQueryRow)) { + throw new InvalidItemException(); + } + + if (!empty($params)) { + $data['_params'] = $params; + } + + foreach ($qb->getDefaultValues() as $k => $v) { + if ($this->get($k, $data) === '') { + $data[$k] = $v; + } + } + + $data = array_merge($qb->getDefaultValues(), $data); + + $item->importFromDatabase($data); + + return $item; + } + + + /** + * @param callable $method + * @param string $object + * @param array $params + * + * @return IQueryRow + * @throws RowNotFoundException + */ + public function getRow(callable $method, string $object = '', array $params = []): IQueryRow { + $cursor = $this->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new RowNotFoundException(); + } + + return $method($data, $this, $object, $params); + } + + + /** + * @param callable $method + * @param string $object + * @param array $params + * + * @return IQueryRow[] + */ + public function getRows(callable $method, string $object = '', array $params = []): array { + $rows = []; + $cursor = $this->execute(); + while ($data = $cursor->fetch()) { + try { + $rows[] = $method($data, $this, $object, $params); + } catch (Exception $e) { + } + } + $cursor->closeCursor(); + + return $rows; + } + + + /** + * @param string $table + * @param array $fields + * @param string $alias + * + * @return $this + */ + public function generateSelect( + string $table, + array $fields, + string $alias = '' + ): self { + $selectFields = array_map( + function (string $item) use ($alias) { + if ($alias === '') { + return $item; + } + + return $alias . '.' . $item; + }, $fields + ); + + $this->select($selectFields) + ->from($table, $alias) + ->setDefaultSelectAlias($alias); + + return $this; + } + + + /** + * @param array $fields + * @param string $alias + * @param string $prefix + * @param array $default + * + * @return $this + */ + public function generateSelectAlias( + array $fields, + string $alias, + string $prefix, + array $default = [] + ): self { + $prefix = trim($prefix) . '_'; + foreach ($default as $k => $v) { + $this->addDefaultValue($prefix . $k, (string)$v); + } + + foreach ($fields as $field) { + $this->selectAlias($alias . '.' . $field, $prefix . $field); + } + + return $this; + } +} diff --git a/lib/Tools/Db/IQueryRow.php b/lib/Tools/Db/IQueryRow.php new file mode 100644 index 0000000..15e695b --- /dev/null +++ b/lib/Tools/Db/IQueryRow.php @@ -0,0 +1,49 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Db; + +/** + * Interface IQueryRow + * + * @package OCA\Backup\Tools\Db + */ +interface IQueryRow { + + /** + * import data to feed the model. + * + * @param array $data + * + * @return IQueryRow + */ + public function importFromDatabase(array $data): self; +} diff --git a/lib/Tools/Exceptions/ArrayNotFoundException.php b/lib/Tools/Exceptions/ArrayNotFoundException.php new file mode 100644 index 0000000..9d3b92d --- /dev/null +++ b/lib/Tools/Exceptions/ArrayNotFoundException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class ArrayNotFoundException + * + * @package OCA\Backup\Tools\Exceptions + */ +class ArrayNotFoundException extends Exception { +} diff --git a/lib/Tools/Exceptions/DateTimeException.php b/lib/Tools/Exceptions/DateTimeException.php new file mode 100644 index 0000000..08e6e42 --- /dev/null +++ b/lib/Tools/Exceptions/DateTimeException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class DateTimeException + * + * @package OCA\Backup\Tools\Exceptions + */ +class DateTimeException extends Exception { +} diff --git a/lib/Tools/Exceptions/InvalidItemException.php b/lib/Tools/Exceptions/InvalidItemException.php new file mode 100644 index 0000000..619e873 --- /dev/null +++ b/lib/Tools/Exceptions/InvalidItemException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class InvalidItemException + * + * @package OCA\Backup\Tools\Exceptions + */ +class InvalidItemException extends Exception { +} diff --git a/lib/Tools/Exceptions/InvalidOriginException.php b/lib/Tools/Exceptions/InvalidOriginException.php new file mode 100644 index 0000000..64dde0c --- /dev/null +++ b/lib/Tools/Exceptions/InvalidOriginException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class InvalidOriginException + * + * @package OCA\Backup\Tools\Exceptions + */ +class InvalidOriginException extends Exception { +} diff --git a/lib/Tools/Exceptions/ItemNotFoundException.php b/lib/Tools/Exceptions/ItemNotFoundException.php new file mode 100644 index 0000000..70d2d2b --- /dev/null +++ b/lib/Tools/Exceptions/ItemNotFoundException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class ItemNotFoundException + * + * @package OCA\Backup\Tools\Exceptions + */ +class ItemNotFoundException extends Exception { +} diff --git a/lib/Tools/Exceptions/JsonNotRequestedException.php b/lib/Tools/Exceptions/JsonNotRequestedException.php new file mode 100644 index 0000000..8c241ec --- /dev/null +++ b/lib/Tools/Exceptions/JsonNotRequestedException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class RequestResultNotJsonException + * + * @package OCA\Backup\Tools\Exceptions + */ +class JsonNotRequestedException extends Exception { +} diff --git a/lib/Tools/Exceptions/MalformedArrayException.php b/lib/Tools/Exceptions/MalformedArrayException.php new file mode 100644 index 0000000..e0ce485 --- /dev/null +++ b/lib/Tools/Exceptions/MalformedArrayException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class MalformedArrayException + * + * @package OCA\Backup\Tools\Exceptions + */ +class MalformedArrayException extends Exception { +} diff --git a/lib/Tools/Exceptions/RequestContentException.php b/lib/Tools/Exceptions/RequestContentException.php new file mode 100644 index 0000000..522abef --- /dev/null +++ b/lib/Tools/Exceptions/RequestContentException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class RequestContentException + * + * @package OCA\Backup\Tools\Exceptions + */ +class RequestContentException extends Exception { +} diff --git a/lib/Tools/Exceptions/RequestNetworkException.php b/lib/Tools/Exceptions/RequestNetworkException.php new file mode 100644 index 0000000..d0ff30e --- /dev/null +++ b/lib/Tools/Exceptions/RequestNetworkException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class RequestNetworkException + * + * @package OCA\Backup\Tools\Exceptions + */ +class RequestNetworkException extends Exception { +} diff --git a/lib/Tools/Exceptions/RequestResultNotJsonException.php b/lib/Tools/Exceptions/RequestResultNotJsonException.php new file mode 100644 index 0000000..5390d47 --- /dev/null +++ b/lib/Tools/Exceptions/RequestResultNotJsonException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class RequestResultNotJsonException + * + * @package OCA\Backup\Tools\Exceptions + */ +class RequestResultNotJsonException extends Exception { +} diff --git a/lib/Tools/Exceptions/RequestResultSizeException.php b/lib/Tools/Exceptions/RequestResultSizeException.php new file mode 100644 index 0000000..c44e066 --- /dev/null +++ b/lib/Tools/Exceptions/RequestResultSizeException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class RequestResultSizeException + * + * @package OCA\Backup\Tools\Exceptions + */ +class RequestResultSizeException extends Exception { +} diff --git a/lib/Tools/Exceptions/RequestServerException.php b/lib/Tools/Exceptions/RequestServerException.php new file mode 100644 index 0000000..60d1490 --- /dev/null +++ b/lib/Tools/Exceptions/RequestServerException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class RequestServerException + * + * @package OCA\Backup\Tools\Exceptions + */ +class RequestServerException extends Exception { +} diff --git a/lib/Tools/Exceptions/RowNotFoundException.php b/lib/Tools/Exceptions/RowNotFoundException.php new file mode 100644 index 0000000..98a11f0 --- /dev/null +++ b/lib/Tools/Exceptions/RowNotFoundException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class RowNotFoundException + * + * @package OCA\Backup\Tools\Exceptions + */ +class RowNotFoundException extends Exception { +} diff --git a/lib/Tools/Exceptions/SignatoryException.php b/lib/Tools/Exceptions/SignatoryException.php new file mode 100644 index 0000000..7efe316 --- /dev/null +++ b/lib/Tools/Exceptions/SignatoryException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class SignatoryException + * + * @package OCA\Backup\Tools\Exceptions + */ +class SignatoryException extends Exception { +} diff --git a/lib/Tools/Exceptions/SignatureException.php b/lib/Tools/Exceptions/SignatureException.php new file mode 100644 index 0000000..9ca8824 --- /dev/null +++ b/lib/Tools/Exceptions/SignatureException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class SignatureException + * + * @package OCA\Backup\Tools\Exceptions + */ +class SignatureException extends Exception { +} diff --git a/lib/Tools/Exceptions/UnknownTypeException.php b/lib/Tools/Exceptions/UnknownTypeException.php new file mode 100644 index 0000000..cc2dd9d --- /dev/null +++ b/lib/Tools/Exceptions/UnknownTypeException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class UnknownTypeException + * + * @package OCA\Backup\Tools\Exceptions + */ +class UnknownTypeException extends Exception { +} diff --git a/lib/Tools/Exceptions/WellKnownLinkNotFoundException.php b/lib/Tools/Exceptions/WellKnownLinkNotFoundException.php new file mode 100644 index 0000000..d5c9709 --- /dev/null +++ b/lib/Tools/Exceptions/WellKnownLinkNotFoundException.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Exceptions; + +use Exception; + +/** + * Class WellKnownLinkNotFoundException + * + * @package OCA\Backup\Tools\Exceptions + */ +class WellKnownLinkNotFoundException extends Exception { +} diff --git a/lib/Tools/IDeserializable.php b/lib/Tools/IDeserializable.php new file mode 100644 index 0000000..925aea5 --- /dev/null +++ b/lib/Tools/IDeserializable.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools; + +interface IDeserializable { + + /** + * @param array $data + * + * @return self + */ + public function import(array $data): self; +} diff --git a/lib/Tools/ISignedModel.php b/lib/Tools/ISignedModel.php new file mode 100644 index 0000000..3054d24 --- /dev/null +++ b/lib/Tools/ISignedModel.php @@ -0,0 +1,55 @@ +<?php + +declare(strict_types=1); + + +/** + * Some tools for myself. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools; + +interface ISignedModel { + + /** + * @param string $signature + * + * @return $this + */ + public function setSignature(string $signature): self; + + /** + * @return string + */ + public function getSignature(): string; + + + /** + * returns array/data to be signed to identify the model + * + * @return array + */ + public function signedData(): array; +} diff --git a/lib/Tools/Model/NCRequest.php b/lib/Tools/Model/NCRequest.php new file mode 100644 index 0000000..3aaa0c4 --- /dev/null +++ b/lib/Tools/Model/NCRequest.php @@ -0,0 +1,174 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use OCP\Http\Client\IClient; + +class NCRequest extends Request { + + + /** @var IClient */ + private $client; + + /** @var array */ + private $clientOptions = []; + + /** @var bool */ + private $localAddressAllowed = false; + + /** @var NCRequestResult */ + private $result; + + /** @var NCRequestResult[] */ + private $previousResults = []; + + + /** + * @param IClient $client + * + * @return $this + */ + public function setClient(IClient $client): self { + $this->client = $client; + + return $this; + } + + /** + * @return IClient + */ + public function getClient(): IClient { + return $this->client; + } + + + /** + * @return array + */ + public function getClientOptions(): array { + return $this->clientOptions; + } + + /** + * @param array $clientOptions + * + * @return self + */ + public function setClientOptions(array $clientOptions): self { + $this->clientOptions = $clientOptions; + + return $this; + } + + + /** + * @return bool + */ + public function isLocalAddressAllowed(): bool { + return $this->localAddressAllowed; + } + + /** + * @param bool $allowed + * + * @return self + */ + public function setLocalAddressAllowed(bool $allowed): self { + $this->localAddressAllowed = $allowed; + + return $this; + } + + + /** + * @return bool + */ + public function hasResult(): bool { + return ($this->result !== null); + } + + /** + * @return NCRequestResult + */ + public function getResult(): NCRequestResult { + return $this->result; + } + + /** + * @param NCRequestResult $result + * + * @return self + */ + public function setResult(NCRequestResult $result): self { + if (!is_null($this->result)) { + $this->previousResults[] = $this->result; + } + + $this->result = $result; + + return $this; + } + + /** + * @return NCRequestResult[] + */ + public function getPreviousResults(): array { + return $this->previousResults; + } + + /** + * @return NCRequestResult[] + */ + public function getAllResults(): array { + return array_values(array_merge([$this->getResult()], $this->previousResults)); + } + + + /** + * @return array + */ + public function jsonSerialize(): array { + $result = null; + if ($this->hasResult()) { + $result = $this->getResult(); + } + + return array_merge( + parent::jsonSerialize(), + [ + 'clientOptions' => $this->getClientOptions(), + 'localAddressAllowed' => $this->isLocalAddressAllowed(), + 'result' => $result + ] + ); + } +} diff --git a/lib/Tools/Model/NCRequestResult.php b/lib/Tools/Model/NCRequestResult.php new file mode 100644 index 0000000..591ff0b --- /dev/null +++ b/lib/Tools/Model/NCRequestResult.php @@ -0,0 +1,321 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use GuzzleHttp\Exception\BadResponseException; +use JsonSerializable; +use OCA\Backup\Tools\Exceptions\RequestContentException; +use OCA\Backup\Tools\Traits\TArrayTools; +use OCP\Http\Client\IResponse; + +class NCRequestResult implements JsonSerializable { + use TArrayTools; + + + public const TYPE_STRING = 0; + public const TYPE_BINARY = 1; + public const TYPE_JSON = 2; + public const TYPE_XRD = 3; + + + /** @var int */ + private $statusCode = 0; + + /** @var array */ + private $headers = []; + + /** @var mixed */ + private $content; + + /** @var array */ + private $contentAsArray = []; + + /** @var int */ + private $contentType = 0; + + /** @var BadResponseException */ + private $exception = null; + + + /** + * NCRequestResult constructor. + * + * @param IResponse|null $response + * @param BadResponseException|null $e + */ + public function __construct(?IResponse $response, ?BadResponseException $e = null) { + if (!is_null($response)) { + $this->setStatusCode($response->getStatusCode()); + $this->setContent($response->getBody()); + $this->setHeaders($response->getHeaders()); + } + + if (!is_null($e)) { + $this->setException($e); + } + + $this->generateMeta(); + } + + + /** + * @return int + */ + public function getStatusCode(): int { + return $this->statusCode; + } + + /** + * @param int $statusCode + * + * @return self + */ + public function setStatusCode(int $statusCode): self { + $this->statusCode = $statusCode; + + return $this; + } + + + /** + * @return array + */ + public function getHeaders(): array { + return $this->headers; + } + + /** + * @param array $headers + * + * @return self + */ + public function setHeaders(array $headers): self { + $this->headers = $headers; + + return $this; + } + + /** + * @param string $key + * + * @return array + */ + public function getHeader(string $key): array { + return $this->getArray($key, $this->headers); + } + + public function withinHeader(string $key, string $needle): bool { + foreach ($this->getHeader($key) as $header) { + if (strpos($header, $needle) !== false) { + return true; + } + } + + return false; + } + + + /** + * @param string $content + * + * @return self + */ + public function setContent(string $content): self { + $this->content = $content; + + return $this; + } + + + /** + * @return string + * @throws RequestContentException + */ + public function getContent(): string { + if (is_null($this->content) || !is_string($this->content)) { + throw new RequestContentException(); + } + + return $this->content; + } + + /** + * @return array + */ + public function getAsArray(): array { + if (empty($this->contentAsArray)) { + $this->generateContentAsArray(); + } + + return $this->contentAsArray; + } + + + /** + * @return string + */ + public function getBinary() { + return $this->content; + } + + + /** + * @return int + */ + public function getContentType(): int { + return $this->contentType; + } + + /** + * @param int $type + * + * @return $this + */ + public function setContentType(int $type): self { + $this->contentType = $type; + + return $this; + } + + /** + * @param int $type + * + * @return bool + */ + public function isContentType(int $type): bool { + return ($this->contentType === $type); + } + + + /** + * + */ + private function generateMeta(): void { + $this->setContentType($this->discoverContentType()); + $this->generateContentAsArray(); + } + + /** + * @return int + */ + private function discoverContentType(): int { + if ($this->withinHeader('Content-Type', 'application/xrd')) { + return self::TYPE_XRD; + } + + if ($this->withinHeader('Content-Type', 'application/json') + || $this->withinHeader('Content-Type', 'application/jrd') + ) { + return self::TYPE_JSON; + } + + try { + $content = $this->getContent(); + } catch (RequestContentException $e) { + return self::TYPE_BINARY; + } + + // in case header failure + $arr = json_decode($content, true); + if (is_array($arr)) { + return self::TYPE_JSON; + } + + return self::TYPE_STRING; + } + + /** + * + */ + private function generateContentAsArray(): void { + try { + $content = $this->getContent(); + if ($this->isContentType(self::TYPE_XRD)) { + $xml = simplexml_load_string($content); + $content = json_encode($xml, JSON_UNESCAPED_SLASHES); + } + + $arr = json_decode($content, true); + if (is_array($arr)) { + $this->contentAsArray = $arr; + } + } catch (RequestContentException $e) { + } + } + + + /** + * @param BadResponseException $e + * + * @return self + */ + public function setException(BadResponseException $e): self { + $this->exception = $e; + $this->setStatusCode($e->getResponse()->getStatusCode()); + + return $this; + } + + /** + * @return BadResponseException + */ + public function getException(): BadResponseException { + return $this->exception; + } + + /** + * @return bool + */ + public function hasException(): bool { + return (!is_null($this->exception)); + } + + + /** + * @return array + */ + public function jsonSerialize(): array { + try { + $content = $this->getContent(); + } catch (RequestContentException $e) { + $content = 'not a string'; + } + + return [ + 'statusCode' => $this->getStatusCode(), + 'headers' => $this->getHeaders(), + 'content' => $content, + 'contentAsArray' => $this->contentAsArray, + 'contentType' => $this->getContentType() + ]; + } +} diff --git a/lib/Tools/Model/NCSignatory.php b/lib/Tools/Model/NCSignatory.php new file mode 100644 index 0000000..b802836 --- /dev/null +++ b/lib/Tools/Model/NCSignatory.php @@ -0,0 +1,294 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use JsonSerializable; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; + +class NCSignatory implements IDeserializable, JsonSerializable { + use TArrayTools; + + + public const SHA256 = 'sha256'; + public const SHA512 = 'sha512'; + + + /** @var string */ + private $instance = ''; + + /** @var string */ + private $id = ''; + + /** @var string */ + private $keyOwner = ''; + + /** @var string */ + private $keyId = ''; + + /** @var string */ + private $publicKey = ''; + + /** @var string */ + private $privateKey = ''; + + /** @var array */ + private $origData = []; + + /** @var string */ + private $algorithm = self::SHA256; + + + /** + * NC22Signatory constructor. + * + * @param string $id + */ + public function __construct(string $id = '') { + $this->id = self::removeFragment($id); + } + + + /** + * @param string $instance + * + * @return self + */ + public function setInstance(string $instance): self { + $this->instance = $instance; + + return $this; + } + + /** + * @return string + */ + public function getInstance(): string { + return $this->instance; + } + + + /** + * @return array + */ + public function getOrigData(): array { + return $this->origData; + } + + /** + * /** + * @param array $data + * + * @return $this + */ + public function setOrigData(array $data): self { + $this->origData = $data; + + return $this; + } + + + /** + * @return string + */ + public function getId(): string { + return $this->id; + } + + /** + * @param string $id + * + * @return self + */ + public function setId(string $id): self { + $this->id = $id; + + return $this; + } + + + /** + * @param string $keyId + * + * @return self + */ + public function setKeyId(string $keyId): self { + $this->keyId = $keyId; + + return $this; + } + + /** + * @return string + */ + public function getKeyId(): string { + return $this->keyId; + } + + + /** + * @param string $keyOwner + * + * @return self + */ + public function setKeyOwner(string $keyOwner): self { + $this->keyOwner = $keyOwner; + + return $this; + } + + /** + * @return string + */ + public function getKeyOwner(): string { + return $this->keyOwner; + } + + + /** + * @param string $publicKey + * + * @return self + */ + public function setPublicKey(string $publicKey): self { + $this->publicKey = $publicKey; + + return $this; + } + + /** + * @param string $privateKey + * + * @return self + */ + public function setPrivateKey(string $privateKey): self { + $this->privateKey = $privateKey; + + return $this; + } + + /** + * @return string + */ + public function getPublicKey(): string { + return $this->publicKey; + } + + /** + * @return string + */ + public function getPrivateKey(): string { + return $this->privateKey; + } + + /** + * @return bool + */ + public function hasPublicKey(): bool { + return ($this->publicKey !== ''); + } + + /** + * @return bool + */ + public function hasPrivateKey(): bool { + return ($this->privateKey !== ''); + } + + + /** + * @param string $algorithm + * + * @return self + */ + public function setAlgorithm(string $algorithm): self { + $this->algorithm = $algorithm; + + return $this; + } + + /** + * @return string + */ + public function getAlgorithm(): string { + return $this->algorithm; + } + + + /** + * @param array $data + * + * @return $this + */ + public function import(array $data): IDeserializable { + if ($this->getId() === '') { + $this->setId($this->get('id', $data)); + } + + $this->setKeyId($this->get('publicKey.id', $data)); + $this->setKeyOwner($this->get('publicKey.owner', $data)); + $this->setPublicKey($this->get('publicKey.publicKeyPem', $data)); + + return $this; + } + + + /** + * @return array + */ + public function jsonSerialize(): array { + return [ + 'id' => $this->getId(), + 'publicKey' => + [ + 'id' => $this->getKeyId(), + 'owner' => $this->getKeyOwner(), + 'publicKeyPem' => $this->getPublicKey() + ] + ]; + } + + + /** + * @param string $id + * + * @return string + */ + public static function removeFragment(string $id): string { + $temp = strtok($id, '#'); + if (is_string($temp)) { + $id = $temp; + } + + return $id; + } +} diff --git a/lib/Tools/Model/NCSignedRequest.php b/lib/Tools/Model/NCSignedRequest.php new file mode 100644 index 0000000..95b2eba --- /dev/null +++ b/lib/Tools/Model/NCSignedRequest.php @@ -0,0 +1,348 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use JsonSerializable; +use OCP\IRequest; + +class NCSignedRequest implements JsonSerializable { + + + /** @var string */ + private $body = ''; + + /** @var int */ + private $time = 0; + + /** @var IRequest */ + private $incomingRequest; + + /** @var NCRequest */ + private $outgoingRequest; + + /** @var string */ + private $origin = ''; + + /** @var string */ + private $digest = ''; + + /** @var SimpleDataStore */ + private $signatureHeader; + + /** @var string */ + private $host = ''; + + /** @var string */ + private $clearSignature = ''; + + /** @var string */ + private $signedSignature = ''; + + /** @var NCSignatory */ + private $signatory; + + + public function __construct(string $body = '') { + $this->setBody($body); + } + + + /** + * IRequest of the incoming request + * incoming + * + * @return IRequest + */ + public function getIncomingRequest(): IRequest { + return $this->incomingRequest; + } + + /** + * @param IRequest $request + * + * @return NCSignedRequest + */ + public function setIncomingRequest(IRequest $request): self { + $this->incomingRequest = $request; + + return $this; + } + + + /** + * NCRequest of the outgoing request + * outgoing + * + * @param NCRequest $request + * + * @return NCSignedRequest + */ + public function setOutgoingRequest(NCRequest $request): self { + $this->outgoingRequest = $request; + + return $this; + } + + /** + * @return NCRequest + */ + public function getOutgoingRequest(): NCRequest { + return $this->outgoingRequest; + } + + + /** + * Body content of the request + * incoming/outgoing + * + * @return string + */ + public function getBody(): string { + return $this->body; + } + + /** + * @param string $body + * + * @return self + */ + public function setBody(string $body): self { + $this->body = $body; + $this->setDigest('SHA-256=' . base64_encode(hash("sha256", utf8_encode($body), true))); + + return $this; + } + + + /** + * Timestamp of the request + * incoming (outgoing ?) + * + * @return int + */ + public function getTime(): int { + return $this->time; + } + + /** + * @param int $time + * + * @return self + */ + public function setTime(int $time): self { + $this->time = $time; + + return $this; + } + + + /** + * Origin of the request, based on the keyId + * incoming + * + * @return string + */ + public function getOrigin(): string { + return $this->origin; + } + + /** + * @param string $origin + * + * @return self + */ + public function setOrigin(string $origin): self { + $this->origin = $origin; + + return $this; + } + + + /** + * @return string + */ + public function getDigest(): string { + return $this->digest; + } + + /** + * @param string $digest + * + * @return $this + */ + public function setDigest(string $digest): self { + $this->digest = $digest; + + return $this; + } + + + /** + * Data from the 'Signature' header + * incoming/outgoing + * + * @return SimpleDataStore + */ + public function getSignatureHeader(): SimpleDataStore { + return $this->signatureHeader; + } + + /** + * @param SimpleDataStore $signatureHeader + * + * @return self + */ + public function setSignatureHeader(SimpleDataStore $signatureHeader): self { + $this->signatureHeader = $signatureHeader; + + return $this; + } + + + /** + * _Clear_ value of the Signature. + * incoming/outgoing + * + * - estimated signature on incoming request + * - generated signature on outgoing request + * + * @param string $clearSignature + * + * @return NCSignedRequest + */ + public function setClearSignature(string $clearSignature): self { + $this->clearSignature = $clearSignature; + + return $this; + } + + /** + * @return string + */ + public function getClearSignature(): string { + return $this->clearSignature; + } + + + /** + * _Signed_ value of the signature. + * /!\ base64_encoded, not RAW /!\ + * + * incoming/outgoing + * + * @param string $signedSignature + * + * @return self + */ + public function setSignedSignature(string $signedSignature): self { + $this->signedSignature = $signedSignature; + + return $this; + } + + /** + * @return string + */ + public function getSignedSignature(): string { + return $this->signedSignature; + } + + + /** + * Host/Address to be used in the signature. + * incoming/outgoing + * + * - incoming should set the local address + * - outgoing should set the recipient address + * + * @param string $host + * + * @return NCSignedRequest + */ + public function setHost(string $host): self { + $this->host = $host; + + return $this; + } + + /** + * @return string + */ + public function getHost(): string { + return $this->host; + } + + + /** + * Signatory used to sign the request + * incoming/outgoing + * + * @param NCSignatory $signatory + */ + public function setSignatory(NCSignatory $signatory): void { + $this->signatory = $signatory; + } + + /** + * @return NCSignatory + */ + public function getSignatory(): NCSignatory { + return $this->signatory; + } + + /** + * @return bool + */ + public function hasSignatory(): bool { + return ($this->signatory !== null); + } + + + /** + * @return array + */ + public function jsonSerialize(): array { + return [ + 'body' => $this->getBody(), + 'time' => $this->getTime(), + 'incomingRequest' => ($this->incomingRequest !== null), + 'outgoingRequest' => $this->outgoingRequest !== null ? $this->getOutgoingRequest() : false, + 'origin' => $this->getOrigin(), + 'digest' => $this->getDigest(), + 'signatureHeader' => ($this->signatureHeader !== null) ? $this->getSignatureHeader() : false, + 'host' => $this->getHost(), + 'clearSignature' => $this->getClearSignature(), + 'signedSignature' => base64_encode($this->getSignedSignature()), + 'signatory' => ($this->hasSignatory()) ? $this->getSignatory() : false, + ]; + } +} diff --git a/lib/Tools/Model/NCWebfinger.php b/lib/Tools/Model/NCWebfinger.php new file mode 100644 index 0000000..c2297fd --- /dev/null +++ b/lib/Tools/Model/NCWebfinger.php @@ -0,0 +1,197 @@ +<?php +/* + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2017 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use JsonSerializable; +use OCA\Backup\Tools\Traits\TArrayTools; + +class NCWebfinger implements JsonSerializable { + use TArrayTools; + + + /** @var string */ + private $subject = ''; + + /** @var array */ + private $aliases = []; + + /** @var array */ + private $properties = []; + + /** @var NCWellKnownLink[] */ + private $links = []; + + + /** + * NC22Webfinger constructor. + * + * @param array $json + */ + public function __construct(array $json = []) { + $this->setSubject($this->get('subject', $json)); + $this->setAliases($this->getArray('subject', $json)); + $this->setProperties($this->getArray('properties', $json)); + + foreach ($this->getArray('links', $json) as $link) { + $this->addLink(new NCWellKnownLink($link)); + } + } + + + /** + * @return string + */ + public function getSubject(): string { + return $this->subject; + } + + /** + * @param string $subject + * + * @return self + */ + public function setSubject(string $subject): self { + $this->subject = $subject; + + return $this; + } + + + /** + * @return array + */ + public function getAliases(): array { + return $this->aliases; + } + + /** + * @param array $aliases + * + * @return self + */ + public function setAliases(array $aliases): self { + $this->aliases = $aliases; + + return $this; + } + + + /** + * @return array + */ + public function getProperties(): array { + return $this->properties; + } + + /** + * @param array $properties + * + * @return self + */ + public function setProperties(array $properties): self { + $this->properties = $properties; + + return $this; + } + + /** + * @param string $key + * + * @return string + */ + public function getProperty(string $key): string { + return $this->get($key, $this->properties); + } + + + /** + * @return NCWellKnownLink[] + */ + public function getLinks(): array { + return $this->links; + } + + /** + * @param NCWellKnownLink[] $links + * + * @return self + */ + public function setLinks(array $links): self { + $this->links = $links; + + return $this; + } + + public function addLink(NCWellKnownLink $link): self { + $this->links[] = $link; + + return $this; + } + + /** + * @return array + */ + public function jsonSerialize(): array { + return array_filter( + [ + 'subject' => $this->getSubject(), + 'aliases' => $this->getAliases(), + 'properties' => $this->getProperties(), + 'links' => $this->getLinks() + ] + ); + } +} diff --git a/lib/Tools/Model/NCWellKnownLink.php b/lib/Tools/Model/NCWellKnownLink.php new file mode 100644 index 0000000..614477a --- /dev/null +++ b/lib/Tools/Model/NCWellKnownLink.php @@ -0,0 +1,222 @@ +<?php +/* + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2017 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use JsonSerializable; +use OCA\Backup\Tools\Traits\TArrayTools; + +class NCWellKnownLink implements JsonSerializable { + use TArrayTools; + + + /** @var string */ + private $rel = ''; + + /** @var string */ + private $type = ''; + + /** @var string */ + private $href = ''; + + /** @var array */ + private $titles = []; + + /** @var array */ + private $properties = []; + + + /** + * NC22WellKnownLink constructor. + * + * @param array $json + */ + public function __construct(array $json = []) { + $this->setRel($this->get('rel', $json)); + $this->setType($this->get('type', $json)); + $this->setHref($this->get('href', $json)); + $this->setTitles($this->getArray('titles', $json)); + $this->setProperties($this->getArray('properties', $json)); + } + + + /** + * @return string + */ + public function getRel(): string { + return $this->rel; + } + + /** + * @param string $rel + * + * @return self + */ + public function setRel(string $rel): self { + $this->rel = $rel; + + return $this; + } + + + /** + * @return string + */ + public function getType(): string { + return $this->type; + } + + /** + * @param string $type + * + * @return self + */ + public function setType(string $type): self { + $this->type = $type; + + return $this; + } + + + /** + * @return string + */ + public function getHref(): string { + return $this->href; + } + + /** + * @param string $href + * + * @return self + */ + public function setHref(string $href): self { + $this->href = $href; + + return $this; + } + + + /** + * @return array + */ + public function getTitles(): array { + return $this->titles; + } + + /** + * @param array $titles + * + * @return self + */ + public function setTitles(array $titles): self { + $this->titles = $titles; + + return $this; + } + + /** + * @param string $key + * + * @return string + */ + public function getTitle(string $key): string { + return $this->get($key, $this->properties); + } + + + /** + * @return array + */ + public function getProperties(): array { + return $this->properties; + } + + /** + * @param array $properties + * + * @return self + */ + public function setProperties(array $properties): self { + $this->properties = $properties; + + return $this; + } + + /** + * @param string $key + * + * @return string + */ + public function getProperty(string $key): string { + return $this->get($key, $this->properties); + } + + + /** + * @return array + */ + public function jsonSerialize(): array { + return array_filter( + [ + 'rel' => $this->getRel(), + 'type' => $this->getType(), + 'href' => $this->getHref(), + 'titles' => $this->getTitles(), + 'properties' => $this->getProperties() + ] + ); + } +} diff --git a/lib/Tools/Model/Request.php b/lib/Tools/Model/Request.php new file mode 100644 index 0000000..f267685 --- /dev/null +++ b/lib/Tools/Model/Request.php @@ -0,0 +1,832 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use JsonSerializable; +use OCA\Backup\Tools\Traits\TArrayTools; + +class Request implements JsonSerializable { + use TArrayTools; + + + public const TYPE_GET = 0; + public const TYPE_POST = 1; + public const TYPE_PUT = 2; + public const TYPE_DELETE = 3; + + + public const QS_VAR_DUPLICATE = 1; + public const QS_VAR_ARRAY = 2; + + + /** @var string */ + private $protocol = ''; + + /** @var array */ + private $protocols = ['https']; + + /** @var string */ + private $host = ''; + + /** @var int */ + private $port = 0; + + /** @var string */ + private $url = ''; + + /** @var string */ + private $baseUrl = ''; + + /** @var int */ + private $type = 0; + + /** @var bool */ + private $binary = false; + + /** @var bool */ + private $verifyPeer = true; + + /** @var bool */ + private $httpErrorsAllowed = false; + + /** @var bool */ + private $followLocation = true; + + /** @var array */ + private $headers = []; + + /** @var array */ + private $cookies = []; + + /** @var array */ + private $params = []; + + /** @var array */ + private $data = []; + + /** @var int */ + private $queryStringType = self::QS_VAR_DUPLICATE; + + /** @var int */ + private $timeout = 10; + + /** @var string */ + private $userAgent = ''; + + /** @var int */ + private $resultCode = 0; + + /** @var string */ + private $contentType = ''; + + + /** + * Request constructor. + * + * @param string $url + * @param int $type + * @param bool $binary + */ + public function __construct(string $url = '', int $type = 0, bool $binary = false) { + $this->url = $url; + $this->type = $type; + $this->binary = $binary; + } + + + /** + * @param string $protocol + * + * @return Request + */ + public function setProtocol(string $protocol): Request { + $this->protocols = [$protocol]; + + return $this; + } + + /** + * @param array $protocols + * + * @return Request + */ + public function setProtocols(array $protocols): Request { + $this->protocols = $protocols; + + return $this; + } + + /** + * @return string[] + */ + public function getProtocols(): array { + return $this->protocols; + } + + /** + * @return string + */ + public function getUsedProtocol(): string { + return $this->protocol; + } + + /** + * @param string $protocol + * + * @return Request + */ + public function setUsedProtocol(string $protocol): Request { + $this->protocol = $protocol; + + return $this; + } + + + /** + * @return string + * @deprecated - 19 - use getHost(); + */ + public function getAddress(): string { + return $this->getHost(); + } + + /** + * @param string $address + * + * @return Request + * @deprecated - 19 - use setHost(); + */ + public function setAddress(string $address): Request { + $this->setHost($address); + + return $this; + } + + /** + * @return string + */ + public function getHost(): string { + return $this->host; + } + + /** + * @param string $host + * + * @return Request + */ + public function setHost(string $host): Request { + $this->host = $host; + + return $this; + } + + + /** + * @return int + */ + public function getPort(): int { + return $this->port; + } + + /** + * @param int $port + * + * @return Request + */ + public function setPort(int $port): Request { + $this->port = $port; + + return $this; + } + + + /** + * @param string $instance + * + * @return Request + */ + public function setInstance(string $instance): Request { + if (strpos($instance, ':') === false) { + $this->setHost($instance); + + return $this; + } + + [$host, $port] = explode(':', $instance, 2); + $this->setHost($host); + if ($port !== '') { + $this->setPort((int)$port); + } + + return $this; + } + + + /** + * @return string + */ + public function getInstance(): string { + $instance = $this->getHost(); + if ($this->getPort() > 0) { + $instance .= ':' . $this->getPort(); + } + + return $instance; + } + + + /** + * @param string $url + * + * @deprecated - 19 - use basedOnUrl(); + */ + public function setAddressFromUrl(string $url) { + $this->basedOnUrl($url); + } + + /** + * @param string $url + */ + public function basedOnUrl(string $url) { + $protocol = parse_url($url, PHP_URL_SCHEME); + if ($protocol === null) { + if (strpos($url, '/') > -1) { + [$address, $baseUrl] = explode('/', $url, 2); + $this->setBaseUrl('/' . $baseUrl); + } else { + $address = $url; + } + if (strpos($address, ':') > -1) { + [$address, $port] = explode(':', $address, 2); + $this->setPort((int)$port); + } + $this->setHost($address); + } else { + $this->setProtocols([$protocol]); + $this->setUsedProtocol($protocol); + $this->setHost(parse_url($url, PHP_URL_HOST)); + $this->setBaseUrl(parse_url($url, PHP_URL_PATH)); + if (is_numeric($port = parse_url($url, PHP_URL_PORT))) { + $this->setPort($port); + } + } + } + + /** + * @param string|null $baseUrl + * + * @return Request + */ + public function setBaseUrl(?string $baseUrl): Request { + if ($baseUrl !== null) { + $this->baseUrl = $baseUrl; + } + + return $this; + } + + /** + * @return bool + */ + public function isBinary(): bool { + return $this->binary; + } + + + /** + * @param bool $verifyPeer + * + * @return $this + */ + public function setVerifyPeer(bool $verifyPeer): Request { + $this->verifyPeer = $verifyPeer; + + return $this; + } + + /** + * @return bool + */ + public function isVerifyPeer(): bool { + return $this->verifyPeer; + } + + + /** + * @param bool $httpErrorsAllowed + * + * @return Request + */ + public function setHttpErrorsAllowed(bool $httpErrorsAllowed): Request { + $this->httpErrorsAllowed = $httpErrorsAllowed; + + return $this; + } + + /** + * @return bool + */ + public function isHttpErrorsAllowed(): bool { + return $this->httpErrorsAllowed; + } + + + /** + * @param bool $followLocation + * + * @return $this + */ + public function setFollowLocation(bool $followLocation): Request { + $this->followLocation = $followLocation; + + return $this; + } + + /** + * @return bool + */ + public function isFollowLocation(): bool { + return $this->followLocation; + } + + + /** + * @return string + * @deprecated - 19 - use getParametersUrl() + addParam() + */ + public function getParsedUrl(): string { + $url = $this->getPath(); + $ak = array_keys($this->getData()); + foreach ($ak as $k) { + if (!is_string($this->data[$k])) { + continue; + } + + $url = str_replace(':' . $k, $this->data[$k], $url); + } + + return $url; + } + + /** + * @return string + */ + public function getParametersUrl(): string { + $url = $this->getPath(); + $ak = array_keys($this->getParams()); + foreach ($ak as $k) { + if (!is_string($this->params[$k])) { + continue; + } + + $url = str_replace(':' . $k, $this->params[$k], $url); + } + + return $url; + } + + + /** + * @return string + */ + public function getPath(): string { + return $this->baseUrl . $this->url; + } + + + /** + * @return string + * @deprecated - 19 - use getPath() + */ + public function getUrl(): string { + return $this->getPath(); + } + + + /** + * @return string + */ + public function getCompleteUrl(): string { + $port = ($this->getPort() > 0) ? ':' . $this->getPort() : ''; + + return $this->getUsedProtocol() . '://' . $this->getHost() . $port . $this->getParametersUrl(); + } + + + /** + * @return int + */ + public function getType(): int { + return $this->type; + } + + + public function addHeader($key, $value): Request { + $header = $this->get($key, $this->headers); + if ($header !== '') { + $header .= ', ' . $value; + } else { + $header = $value; + } + + $this->headers[$key] = $header; + + return $this; + } + + /** + * @return array + */ + public function getHeaders(): array { + return array_merge(['User-Agent' => $this->getUserAgent()], $this->headers); + } + + /** + * @param array $headers + * + * @return Request + */ + public function setHeaders(array $headers): Request { + $this->headers = $headers; + + return $this; + } + + + /** + * @return array + */ + public function getCookies(): array { + return $this->cookies; + } + + /** + * @param array $cookies + * + * @return Request + */ + public function setCookies(array $cookies): Request { + $this->cookies = $cookies; + + return $this; + } + + + /** + * @param int $queryStringType + * + * @return Request + */ + public function setQueryStringType(int $queryStringType): self { + $this->queryStringType = $queryStringType; + + return $this; + } + + /** + * @return int + */ + public function getQueryStringType(): int { + return $this->queryStringType; + } + + + /** + * @return array + */ + public function getData(): array { + return $this->data; + } + + + /** + * @param array $data + * + * @return Request + */ + public function setData(array $data): Request { + $this->data = $data; + + return $this; + } + + + /** + * @param string $data + * + * @return Request + */ + public function setDataJson(string $data): Request { + $this->setData(json_decode($data, true)); + + return $this; + } + + + /** + * @param JsonSerializable $data + * + * @return Request + */ + public function setDataSerialize(JsonSerializable $data): Request { + $this->setDataJson(json_encode($data)); + + return $this; + } + + + /** + * @return array + */ + public function getParams(): array { + return $this->params; + } + + /** + * @param array $params + * + * @return Request + */ + public function setParams(array $params): Request { + $this->params = $params; + + return $this; + } + + + /** + * @param string $k + * @param string $v + * + * @return Request + */ + public function addParam(string $k, string $v): Request { + $this->params[$k] = $v; + + return $this; + } + + + /** + * @param string $k + * @param int $v + * + * @return Request + */ + public function addParamInt(string $k, int $v): Request { + $this->params[$k] = $v; + + return $this; + } + + + /** + * @param string $k + * @param string $v + * + * @return Request + */ + public function addData(string $k, string $v): Request { + $this->data[$k] = $v; + + return $this; + } + + + /** + * @param string $k + * @param int $v + * + * @return Request + */ + public function addDataInt(string $k, int $v): Request { + $this->data[$k] = $v; + + return $this; + } + + + /** + * @return string + */ + public function getDataBody(): string { + return json_encode($this->getData()); + } + + /** + * @return string + * @deprecated - 19 - use getUrlParams(); + */ + public function getUrlData(): string { + if ($this->getData() === []) { + return ''; + } + + return preg_replace( + '/([(%5B)]{1})[0-9]+([(%5D)]{1})/', '$1$2', http_build_query($this->getData()) + ); + } + + /** + * @return string + * @deprecated - 21 - use getQueryString(); + */ + public function getUrlParams(): string { + if ($this->getParams() === []) { + return ''; + } + + return preg_replace( + '/([(%5B)]{1})[0-9]+([(%5D)]{1})/', '$1$2', http_build_query($this->getParams()) + ); + } + + + /** + * @param int $type + * + * @return string + */ + public function getQueryString(): string { + if (empty($this->getParams())) { + return ''; + } + + switch ($this->getQueryStringType()) { + case self::QS_VAR_ARRAY: + return '?' . http_build_query($this->getParams()); + + case self::QS_VAR_DUPLICATE: + default: + return '?' . preg_replace( + '/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', http_build_query($this->getParams()) + ); + } + } + + + /** + * @return int + */ + public function getTimeout(): int { + return $this->timeout; + } + + /** + * @param int $timeout + * + * @return Request + */ + public function setTimeout(int $timeout): Request { + $this->timeout = $timeout; + + return $this; + } + + + /** + * @return string + */ + public function getUserAgent(): string { + return $this->userAgent; + } + + /** + * @param string $userAgent + * + * @return Request + */ + public function setUserAgent(string $userAgent): Request { + $this->userAgent = $userAgent; + + return $this; + } + + + /** + * @return int + */ + public function getResultCode(): int { + return $this->resultCode; + } + + /** + * @param int $resultCode + * + * @return Request + */ + public function setResultCode(int $resultCode): Request { + $this->resultCode = $resultCode; + + return $this; + } + + + /** + * @return string + */ + public function getContentType(): string { + return $this->contentType; + } + + /** + * @param string $contentType + * + * @return Request + */ + public function setContentType(string $contentType): Request { + $this->contentType = $contentType; + + return $this; + } + + + /** + * @return array + */ + public function jsonSerialize(): array { + return [ + 'protocols' => $this->getProtocols(), + 'used_protocol' => $this->getUsedProtocol(), + 'port' => $this->getPort(), + 'host' => $this->getHost(), + 'url' => $this->getPath(), + 'timeout' => $this->getTimeout(), + 'type' => $this->getType(), + 'cookies' => $this->getCookies(), + 'headers' => $this->getHeaders(), + 'params' => $this->getParams(), + 'data' => $this->getData(), + 'userAgent' => $this->getUserAgent(), + 'followLocation' => $this->isFollowLocation(), + 'verifyPeer' => $this->isVerifyPeer(), + 'binary' => $this->isBinary() + ]; + } + + + /** + * @param string $type + * + * @return int + */ + public static function type(string $type): int { + switch (strtoupper($type)) { + case 'GET': + return self::TYPE_GET; + case 'POST': + return self::TYPE_POST; + case 'PUT': + return self::TYPE_PUT; + case 'DELETE': + return self::TYPE_DELETE; + } + + return 0; + } + + + public static function method(int $type): string { + switch ($type) { + case self::TYPE_GET: + return 'get'; + case self::TYPE_POST: + return 'post'; + case self::TYPE_PUT: + return 'put'; + case self::TYPE_DELETE: + return 'delete'; + } + + return ''; + } +} diff --git a/lib/Tools/Model/SimpleDataStore.php b/lib/Tools/Model/SimpleDataStore.php new file mode 100644 index 0000000..574614f --- /dev/null +++ b/lib/Tools/Model/SimpleDataStore.php @@ -0,0 +1,487 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +use JsonSerializable; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\Exceptions\ItemNotFoundException; +use OCA\Backup\Tools\Exceptions\MalformedArrayException; +use OCA\Backup\Tools\Exceptions\UnknownTypeException; +use OCA\Backup\Tools\IDeserializable; +use OCA\Backup\Tools\Traits\TArrayTools; + +class SimpleDataStore implements JsonSerializable { + use TArrayTools; + + + /** @var array */ + private $data; + + + /** + * SimpleDataStore constructor. + * + * @param array|null $data + */ + public function __construct(?array $data = []) { + if (!is_array($data)) { + $data = []; + } + + $this->data = $data; + } + + public function default(array $default = []): void { + $this->data = array_merge($default, $this->data); + } + + + /** + * @param string $key + * @param string $value + * + * @return SimpleDataStore + */ + public function s(string $key, string $value): self { + $this->data[$key] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return string + */ + public function g(string $key): string { + return $this->get($key, $this->data); + } + + /** + * @param string $key + * + * @return $this + */ + public function u(string $key): self { + if ($this->hasKey($key)) { + unset($this->data[$key]); + } + + return $this; + } + + /** + * @param string $key + * @param string $value + * + * @return SimpleDataStore + */ + public function a(string $key, string $value): self { + if (!array_key_exists($key, $this->data)) { + $this->data[$key] = []; + } + + $this->data[$key][] = $value; + + return $this; + } + + + /** + * @param string $key + * @param int $value + * + * @return SimpleDataStore + */ + public function sInt(string $key, int $value): self { + $this->data[$key] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return int + */ + public function gInt(string $key): int { + return $this->getInt($key, $this->data); + } + + /** + * @param string $key + * @param int $value + * + * @return SimpleDataStore + */ + public function aInt(string $key, int $value): self { + if (!array_key_exists($key, $this->data)) { + $this->data[$key] = []; + } + + $this->data[$key][] = $value; + + return $this; + } + + + /** + * @param string $key + * @param bool $value + * + * @return SimpleDataStore + */ + public function sBool(string $key, bool $value): self { + $this->data[$key] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return bool + */ + public function gBool(string $key): bool { + return $this->getBool($key, $this->data); + } + + /** + * @param string $key + * @param bool $value + * + * @return SimpleDataStore + */ + public function aBool(string $key, bool $value): self { + if (!array_key_exists($key, $this->data)) { + $this->data[$key] = []; + } + + $this->data[$key][] = $value; + + return $this; + } + + + /** + * @param string $key + * @param array $values + * + * @return SimpleDataStore + */ + public function sArray(string $key, array $values): self { + $this->data[$key] = $values; + + return $this; + } + + /** + * @param string $key + * + * @return array + */ + public function gArray(string $key): array { + return $this->getArray($key, $this->data); + } + + /** + * @param string $key + * @param array $values + * + * @return SimpleDataStore + */ + public function aArray(string $key, array $values): self { + if (!array_key_exists($key, $this->data)) { + $this->data[$key] = []; + } + + $this->data[$key] = array_merge($this->data[$key], $values); + + return $this; + } + + + /** + * @param string $key + * @param JsonSerializable $value + * + * @return SimpleDataStore + */ + public function sObj(string $key, JsonSerializable $value): self { + $this->data[$key] = $value; + + return $this; + } + + + /** + * @param string $key + * @param string $class + * + * @return JsonSerializable[] + */ + public function gObjs(string $key, string $class = ''): array { + $list = $this->gArray($key); + $result = []; + foreach ($list as $item) { + $data = new SimpleDataStore([$key => $item]); + $result[] = $data->gObj($key, $class); + } + + return array_filter($result); + } + + + /** + * @param string $key + * @param string $class + * + * @return null|JsonSerializable + * @throws InvalidItemException + * @throws UnknownTypeException + * @throws ItemNotFoundException + */ + public function gObj(string $key, string $class = ''): ?JsonSerializable { + $type = $this->typeOf($key, $this->data); + + if ($type === self::$TYPE_NULL) { + if ($class === '') { + return null; + } + + throw new InvalidItemException(); + } + + if ($type === self::$TYPE_SERIALIZABLE) { + return $this->getObj($key, $this->data); + } + + if ($type === self::$TYPE_ARRAY && $class !== '') { + $item = new $class(); + if (!$item instanceof IDeserializable && !$item instanceof JsonSerializable) { + throw new InvalidItemException( + $class . ' does not implement IDeserializable and JsonSerializable' + ); + } + + $item->import($this->getArray($key, $this->data)); + + return $item; + } + + throw new InvalidItemException(); + } + + /** + * @param string $key + * @param JsonSerializable $value + * + * @return SimpleDataStore + */ + public function aObj(string $key, JsonSerializable $value): self { + if (!array_key_exists($key, $this->data)) { + $this->data[$key] = []; + } + + $this->data[$key][] = $value; + + return $this; + } + + + /** + * @param string $key + * @param SimpleDataStore $data + * + * @return $this + */ + public function sData(string $key, SimpleDataStore $data): self { + $this->data[$key] = $data->gAll(); + + return $this; + } + + /** + * @param string $key + * @param SimpleDataStore $data + * + * @return $this + */ + public function aData(string $key, SimpleDataStore $data): self { + if (!array_key_exists($key, $this->data) || !is_array($this->data[$key])) { + $this->data[$key] = []; + } + + $this->data[$key][] = $data->gAll(); + + return $this; + } + + /** + * @param string $key + * + * @return SimpleDataStore + */ + public function gData(string $key): SimpleDataStore { + return new SimpleDataStore($this->getArray($key, $this->data)); + } + + + /** + * @param string $key + * + * @return mixed + * @throws ItemNotFoundException + */ + public function gItem(string $key) { + if (!array_key_exists($key, $this->data)) { + throw new ItemNotFoundException(); + } + + return $this->data[$key]; + } + + + /** + * @return array + */ + public function gAll(): array { + return $this->data; + } + + /** + * @param array $data + * + * @return SimpleDataStore + */ + public function sAll(array $data): self { + $this->data = $data; + + return $this; + } + + + public function keys(): array { + return array_keys($this->data); + } + + /** + * @param string $key + * + * @return bool + */ + public function hasKey(string $key): bool { + return (array_key_exists($key, $this->data)); + } + + + /** + * @param array $keys + * + * @param bool $must + * + * @return bool + * @throws MalformedArrayException + */ + public function hasKeys(array $keys, bool $must = false): bool { + foreach ($keys as $key) { + if (!$this->haveKey($key)) { + if ($must) { + throw new MalformedArrayException($key . ' missing in ' . json_encode($this->keys())); + } + + return false; + } + } + + return true; + } + + + /** + * @param array $keys + * @param bool $must + * + * @return bool + * @throws MalformedArrayException + * @deprecated + */ + public function haveKeys(array $keys, bool $must = false): bool { + return $this->hasKeys($keys, $must); + } + + /** + * @param string $key + * + * @return bool + * @deprecated + */ + public function haveKey(string $key): bool { + return $this->hasKey($key); + } + + + /** + * @param string $json + * + * @return $this + */ + public function json(string $json): self { + $data = json_decode($json, true); + if (is_array($data)) { + $this->data = $data; + } + + return $this; + } + + /** + * @param JsonSerializable $obj + * + * @return $this + */ + public function obj(JsonSerializable $obj): self { + $data = $obj->jsonSerialize(); + if (is_array($data)) { + $this->data = $data; + } + + return $this; + } + + /** + * @return array + */ + public function jsonSerialize(): array { + return $this->data; + } +} diff --git a/lib/Tools/Model/TreeNode.php b/lib/Tools/Model/TreeNode.php new file mode 100644 index 0000000..babca35 --- /dev/null +++ b/lib/Tools/Model/TreeNode.php @@ -0,0 +1,232 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Model; + +class TreeNode { + + + /** @var self[] */ + private $children = []; + + /** @var self */ + private $parent; + + /** @var SimpleDataStore */ + private $item; + + + /** @var self */ + private $currentChild; + + /** @var bool */ + private $displayed = false; + + /** @var bool */ + private $splited = false; + + + /** + * NC22TreeNode constructor. + * + * @param self|null $parent + * @param SimpleDataStore $item + */ + public function __construct(?TreeNode $parent, SimpleDataStore $item) { + $this->parent = $parent; + $this->item = $item; + + if ($this->parent !== null) { + $this->parent->addChild($this); + } + } + + /** + * @return bool + */ + public function isRoot(): bool { + return (is_null($this->parent)); + } + + + /** + * @param array $children + * + * @return TreeNode + */ + public function setChildren(array $children): self { + $this->children = $children; + + return $this; + } + + /** + * @param TreeNode $child + * + * @return $this + */ + public function addChild(TreeNode $child): self { + $this->children[] = $child; + + return $this; + } + + + /** + * @return SimpleDataStore + */ + public function getItem(): SimpleDataStore { + $this->displayed = true; + + return $this->item; + } + + + /** + * @return TreeNode + */ + public function getParent(): TreeNode { + return $this->parent; + } + + + /** + * @return $this + */ + public function getRoot(): TreeNode { + if ($this->isRoot()) { + return $this; + } + + return $this->getParent()->getRoot(); + } + + + /** + * @return TreeNode[] + */ + public function getPath(): array { + if ($this->isRoot()) { + return [$this]; + } + + return array_merge($this->parent->getPath(), [$this]); + } + + + /** + * @return int + */ + public function getLevel(): int { + if ($this->isRoot()) { + return 0; + } + + return $this->getParent()->getLevel() + 1; + } + + + /** + * @return TreeNode|null + */ + public function current(): ?TreeNode { + if (!$this->isDisplayed()) { + return $this; + } + + $this->splited = true; + if ($this->initCurrentChild()) { + $next = $this->getCurrentChild()->current(); + if (!is_null($next)) { + return $next; + } + } + + if (!$this->haveNext()) { + return null; + } + + return $this->next(); + } + + + /** + * @return TreeNode + */ + private function next(): TreeNode { + $this->currentChild = array_shift($this->children); + + return $this->currentChild; + } + + /** + * @return bool + */ + public function haveNext(): bool { + return !empty($this->children); + } + + + /** + * @return bool + */ + private function initCurrentChild(): bool { + if (is_null($this->currentChild)) { + if (!$this->haveNext()) { + return false; + } + $this->next(); + } + + return true; + } + + /** + * @return TreeNode|null + */ + private function getCurrentChild(): ?TreeNode { + return $this->currentChild; + } + + /** + * @return bool + */ + private function isDisplayed(): bool { + return $this->displayed; + } + + /** + * @return bool + */ + public function isSplited(): bool { + return $this->splited; + } +} diff --git a/lib/Tools/Traits/TArrayTools.php b/lib/Tools/Traits/TArrayTools.php new file mode 100644 index 0000000..ced1798 --- /dev/null +++ b/lib/Tools/Traits/TArrayTools.php @@ -0,0 +1,432 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use Exception; +use JsonSerializable; +use OCA\Backup\Tools\Exceptions\ArrayNotFoundException; +use OCA\Backup\Tools\Exceptions\ItemNotFoundException; +use OCA\Backup\Tools\Exceptions\MalformedArrayException; +use OCA\Backup\Tools\Exceptions\UnknownTypeException; + +trait TArrayTools { + public static $TYPE_NULL = 'Null'; + public static $TYPE_STRING = 'String'; + public static $TYPE_ARRAY = 'Array'; + public static $TYPE_BOOLEAN = 'Boolean'; + public static $TYPE_INTEGER = 'Integer'; + public static $TYPE_SERIALIZABLE = 'Serializable'; + + + /** + * @param string $k + * @param array $arr + * @param string $default + * + * @return string + */ + protected function get(string $k, array $arr, string $default = ''): string { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->get($subs[1], $r, $default); + } else { + return $default; + } + } + + if ($arr[$k] === null || !is_string($arr[$k]) && (!is_int($arr[$k]))) { + return $default; + } + + return (string)$arr[$k]; + } + + + /** + * @param string $k + * @param array $arr + * @param int $default + * + * @return int + */ + protected function getInt(string $k, array $arr, int $default = 0): int { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->getInt($subs[1], $r, $default); + } else { + return $default; + } + } + + if ($arr[$k] === null) { + return $default; + } + + return intval($arr[$k]); + } + + + /** + * @param string $k + * @param array $arr + * @param float $default + * + * @return float + */ + protected function getFloat(string $k, array $arr, float $default = 0): float { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->getFloat($subs[1], $r, $default); + } else { + return $default; + } + } + + if ($arr[$k] === null) { + return $default; + } + + return intval($arr[$k]); + } + + + /** + * @param string $k + * @param array $arr + * @param bool $default + * + * @return bool + */ + protected function getBool(string $k, array $arr, bool $default = false): bool { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + return $this->getBool($subs[1], $arr[$subs[0]], $default); + } else { + return $default; + } + } + + if ($arr[$k] === null) { + return $default; + } + + if (is_bool($arr[$k])) { + return $arr[$k]; + } + + $sk = (string)$arr[$k]; + if ($sk === '1' || strtolower($sk) === 'true') { + return true; + } + + if ($sk === '0' || strtolower($sk) === 'false') { + return false; + } + + return $default; + } + + + /** + * @param string $k + * @param array $arr + * @param JsonSerializable|null $default + * + * @return mixed + */ + protected function getObj(string $k, array $arr, ?JsonSerializable $default = null): ?JsonSerializable { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + return $this->getObj($subs[1], $arr[$subs[0]], $default); + } else { + return $default; + } + } + + return $arr[$k]; + } + + + /** + * @param string $k + * @param array $arr + * @param array $default + * + * @return array + */ + protected function getArray(string $k, array $arr, array $default = []): array { + if (!array_key_exists($k, $arr)) { + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return $default; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return $default; + } + + return $this->getArray($subs[1], $r, $default); + } else { + return $default; + } + } + + $r = $arr[$k]; + if (!is_array($r) && !is_string($r)) { + return $default; + } + + if (is_string($r)) { + $r = json_decode($r, true); + } + + if (!is_array($r)) { + return $default; + } + + return $r; + } + + + /** + * @param string $k + * @param array $arr + * + * @return bool + */ + public function validKey(string $k, array $arr): bool { + if (array_key_exists($k, $arr)) { + return true; + } + + $subs = explode('.', $k, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + return false; + } + + $r = $arr[$subs[0]]; + if (!is_array($r)) { + return false; + } + + return $this->validKey($subs[1], $r); + } + + return false; + } + + + /** + * @param string $k + * @param array $arr + * @param array $import + * @param array $default + * + * @return array + */ + protected function getList(string $k, array $arr, array $import, array $default = []): array { + $list = $this->getArray($k, $arr, $default); + + $r = []; + [$obj, $method] = $import; + foreach ($list as $item) { + try { + $o = new $obj(); + $o->$method($item); + + $r[] = $o; + } catch (Exception $e) { + } + } + + return $r; + } + + + /** + * @param string $k + * @param string $value + * @param array $list + * + * @return mixed + * @throws ArrayNotFoundException + */ + protected function extractArray(string $k, string $value, array $list) { + foreach ($list as $arr) { + if (!array_key_exists($k, $arr)) { + continue; + } + + if ($arr[$k] === $value) { + return $arr; + } + } + + throw new ArrayNotFoundException(); + } + + + /** + * @param string $key + * @param array $arr + * @param bool $root + * + * @return string + * @throws ItemNotFoundException + * @throws UnknownTypeException + */ + public function typeOf(string $key, array $arr, bool $root = true): string { + if (array_key_exists($key, $arr)) { + $item = $arr[$key]; + + if (is_null($item)) { + return self::$TYPE_NULL; + } + + if (is_string($item)) { + return self::$TYPE_STRING; + } + + if (is_array($item)) { + return self::$TYPE_ARRAY; + } + + if (is_bool($item)) { + return self::$TYPE_BOOLEAN; + } + + if (is_int($item)) { + return self::$TYPE_INTEGER; + } + + if ($item instanceof JsonSerializable) { + return self::$TYPE_SERIALIZABLE; + } + + throw new UnknownTypeException(); + } + + $subs = explode('.', $key, 2); + if (sizeof($subs) > 1) { + if (!array_key_exists($subs[0], $arr)) { + throw new ItemNotFoundException(); + } + + $r = $arr[$subs[0]]; + if (is_array($r)) { + return $this->typeOf($subs[1], $r); + } + } + + throw new ItemNotFoundException(); + } + + + /** + * @param array $keys + * @param array $arr + * + * @throws MalformedArrayException + */ + protected function mustContains(array $keys, array $arr) { + foreach ($keys as $key) { + if (!array_key_exists($key, $arr)) { + throw new MalformedArrayException( + 'source: ' . json_encode($arr) . ' - missing key: ' . $key + ); + } + } + } + + + /** + * @param array $arr + */ + protected function cleanArray(array &$arr) { + $arr = array_filter( + $arr, + function ($v) { + if (is_string($v)) { + return ($v !== ''); + } + if (is_array($v)) { + return !empty($v); + } + + return true; + } + ); + } +} diff --git a/lib/Tools/Traits/TAsync.php b/lib/Tools/Traits/TAsync.php new file mode 100644 index 0000000..cc29458 --- /dev/null +++ b/lib/Tools/Traits/TAsync.php @@ -0,0 +1,75 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use JsonSerializable; + +trait TAsync { + use TNCSetup; + + + /** @var string */ + public static $SETUP_TIME_LIMIT = 'async_time_limit'; + + + /** + * Hacky way to async the rest of the process without keeping client on hold. + * + * @param string $result + */ + public function async(string $result = ''): void { + if (ob_get_contents() !== false) { + ob_end_clean(); + } + + header('Connection: close'); + header('Content-Encoding: none'); + ignore_user_abort(); + $timeLimit = $this->setupInt(self::$SETUP_TIME_LIMIT); + set_time_limit(($timeLimit > 0) ? $timeLimit : 0); + ob_start(); + + echo($result); + + $size = ob_get_length(); + header('Content-Length: ' . $size); + ob_end_flush(); + flush(); + } + + /** + * @param JsonSerializable $obj + */ + public function asyncObj(JsonSerializable $obj): void { + $this->async(json_encode($obj)); + } +} diff --git a/lib/Tools/Traits/TConsoleTree.php b/lib/Tools/Traits/TConsoleTree.php new file mode 100644 index 0000000..4d5ebf4 --- /dev/null +++ b/lib/Tools/Traits/TConsoleTree.php @@ -0,0 +1,143 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use OCA\Backup\Tools\Model\TreeNode; +use Symfony\Component\Console\Output\ConsoleOutput; + +trait TConsoleTree { + + + /** + * @param TreeNode $root + * @param callable $method + * @param array $config + */ + public function drawTree( + TreeNode $root, + callable $method, + array $config = [ + 'height' => 1, + 'node-spacing' => 0, + 'item-spacing' => 0, + ] + ): void { + $config = array_merge( + [ + 'height' => 1, + 'node-spacing' => 0, + 'item-spacing' => 0 + ], $config + ); + + $output = new ConsoleOutput(); + $prec = 0; + + while (true) { + $node = $root->current(); + if ($node === null) { + return; + } + + $path = $node->getPath(); + array_pop($path); + + $line = $empty = $spacing = ''; + $p = 0; + foreach ($path as $k => $i) { + $line .= ' '; + $empty .= ' '; + if ($k === array_key_last($path)) { + if ($i->haveNext()) { + $line .= '├'; + $empty .= '│'; + } else { + $line .= '└'; + $empty .= ' '; + } + $line .= '── '; + $empty .= ' '; + } else { + if ($i->haveNext()) { + $line .= '│'; + $empty .= '│'; + } else { + $line .= ' '; + $empty .= ' '; + } + $line .= ' '; + $empty .= ' '; + } + $p++; + } + + if ($p < $prec) { + for ($i = 0; $i < $config['node-spacing']; $i++) { + $spacing = substr($empty, 0, -3); + if (substr($spacing, -1) === ' ') { + $spacing = substr($spacing, 0, -1) . '│'; + } + $output->writeln($spacing); + } + } + + $prec = $p; + + for ($i = 1; $i <= $config['height']; $i++) { + $draw = $method($node->getItem(), $i); + if ($draw === '') { + continue; + } + if ($i === 1) { + $output->write($line); + } else { + $output->write($empty); + } + $output->writeln($draw); + } + + if ($node->haveNext()) { + $empty .= ' │'; + } + + if (!$node->isSplited() && $node->haveNext()) { + for ($i = 0; $i < $config['node-spacing']; $i++) { + $output->writeln($empty); + } + } + + for ($i = 0; $i < $config['item-spacing']; $i++) { + $output->writeln($empty); + } + } + } +} diff --git a/lib/Tools/Traits/TDeserialize.php b/lib/Tools/Traits/TDeserialize.php new file mode 100644 index 0000000..a489653 --- /dev/null +++ b/lib/Tools/Traits/TDeserialize.php @@ -0,0 +1,143 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use JsonSerializable; +use OCA\Backup\Tools\Exceptions\InvalidItemException; +use OCA\Backup\Tools\IDeserializable; + +trait TDeserialize { + + + /** + * @param JsonSerializable $model + * + * @return array + */ + public function serialize(JsonSerializable $model): array { + return json_decode(json_encode($model), true); + } + + /** + * @param array $data + * + * @return array + */ + public function serializeArray(array $data): array { + return json_decode(json_encode($data), true); + } + + + /** + * @param array $data + * @param string $class + * + * @return IDeserializable + * @throws InvalidItemException + */ + public function deserialize(array $data, string $class): IDeserializable { + if ($class instanceof IDeserializable) { + throw new InvalidItemException(get_class($class) . ' does not implement IDeserializable'); + } + + /** @var IDeserializable $item */ + $item = new $class; + $item->import($data); + + return $item; + } + + + + /** + * @param array $data + * @param string $class + * @param bool $associative + * + * @return IDeserializable[] + */ + public function deserializeArray(array $data, string $class, bool $associative = false): array { + $arr = []; + foreach ($data as $key => $entry) { + if (!is_array($entry)) { + continue; + } + + try { + if ($associative) { + $arr[$key] = $this->deserialize($entry, $class); + } else { + $arr[] = $this->deserialize($entry, $class); + } + } catch (InvalidItemException $e) { + } + } + + return $arr; + } + + + /** + * @param string $json + * @param string $class + * + * @return IDeserializable[] + * @throws InvalidItemException + */ + public function deserializeList(string $json, string $class): array { + $arr = []; + $data = json_decode($json, true); + if (!is_array($data)) { + return $arr; + } + + foreach ($data as $entry) { + $arr[] = $this->deserialize($entry, $class); + } + + return $arr; + } + + + /** + * @param string $json + * @param string $class + * + * @return IDeserializable + * @throws InvalidItemException + */ + public function deserializeJson(string $json, string $class): IDeserializable { + $data = json_decode($json, true); + + return $this->deserialize($data, $class); + } +} diff --git a/lib/Tools/Traits/TFileTools.php b/lib/Tools/Traits/TFileTools.php new file mode 100644 index 0000000..b328dd8 --- /dev/null +++ b/lib/Tools/Traits/TFileTools.php @@ -0,0 +1,47 @@ +<?php + +declare(strict_types=1); + + +/** + * Some tools for myself. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +trait TFileTools { + + /** + * @param $stream + * + * @return string + */ + protected function getChecksumFromStream($stream): string { + $ctx = hash_init('md5'); + hash_update_stream($ctx, $stream); + + return hash_final($ctx); + } +} diff --git a/lib/Tools/Traits/TNCController.php b/lib/Tools/Traits/TNCController.php new file mode 100644 index 0000000..d10b785 --- /dev/null +++ b/lib/Tools/Traits/TNCController.php @@ -0,0 +1,113 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use OC; +use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException; +use OCA\Backup\Tools\Exceptions\JsonNotRequestedException; +use OCP\IRequest; +use OCP\IUserSession; + +trait TNCController { + + /** + * use this one if a method from a Controller is only PublicPage when remote client asking for Json + * + * try { + * $this->publicPageJsonLimited(); + * return new DataResponse(['test' => 42]); + * } catch (JsonNotRequestedException $e) {} + * + * + * @throws NotLoggedInException + * @throws JsonNotRequestedException + */ + public function publicPageJsonLimited(): void { + if (!$this->jsonRequested()) { + if (!OC::$server->get(IUserSession::class) + ->isLoggedIn()) { + throw new NotLoggedInException(); + } + + throw new JsonNotRequestedException(); + } + } + + + /** + * @return bool + */ + public function jsonRequested(): bool { + return ($this->areWithinAcceptHeader( + [ + 'application/json', + 'application/ld+json', + 'application/activity+json' + ] + )); + } + + + /** + * @param array $needles + * + * @return bool + */ + public function areWithinAcceptHeader(array $needles): bool { + $request = OC::$server->get(IRequest::class); + $accepts = array_map([$this, 'trimHeader'], explode(',', $request->getHeader('Accept'))); + + foreach ($accepts as $accept) { + if (in_array($accept, $needles)) { + return true; + } + } + + return false; + } + + + /** + * @param string $header + * + * @return string + */ + private function trimHeader(string $header): string { + $header = trim($header); + $pos = strpos($header, ';'); + if ($pos === false) { + return $header; + } + + return substr($header, 0, $pos); + } +} diff --git a/lib/Tools/Traits/TNCLocalSignatory.php b/lib/Tools/Traits/TNCLocalSignatory.php new file mode 100644 index 0000000..5d67495 --- /dev/null +++ b/lib/Tools/Traits/TNCLocalSignatory.php @@ -0,0 +1,111 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use OC; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Model\NCSignatory; +use OCP\IConfig; + +trait TNCLocalSignatory { + use TNCSignatory; + + public static $SIGNATORIES_APP = 'signatories'; + + + /** + * @param NCSignatory $signatory + * @param bool $generate + * + * @throws SignatoryException + */ + public function fillSimpleSignatory(NCSignatory $signatory, bool $generate = false): void { + $app = $this->setup('app', '', self::$SIGNATORIES_APP); + $signatories = json_decode(OC::$server->get(IConfig::class)->getAppValue($app, 'key_pairs'), true); + if (!is_array($signatories)) { + $signatories = []; + } + + $sign = $this->getArray($signatory->getId(), $signatories); + if (!empty($sign)) { + $signatory->setKeyId($this->get('keyId', $sign)) + ->setKeyOwner($this->get('keyOwner', $sign)) + ->setPublicKey($this->get('publicKey', $sign)) + ->setPrivateKey($this->get('privateKey', $sign)); + + return; + } + + if (!$generate) { + throw new SignatoryException('signatory not found'); + } + + $this->createSimpleSignatory($signatory); + } + + + /** + * @param NCSignatory $signatory + */ + public function createSimpleSignatory(NCSignatory $signatory): void { + $app = $this->setup('app', '', self::$SIGNATORIES_APP); + $signatory->setKeyId($signatory->getId() . '#main-key'); + $signatory->setKeyOwner($signatory->getId()); + $this->generateKeys($signatory); + + $signatories = + json_decode(OC::$server->get(IConfig::class)->getAppValue($app, 'key_pairs', '[]'), true); + $signatories[$signatory->getId()] = [ + 'keyId' => $signatory->getKeyId(), + 'keyOwner' => $signatory->getKeyOwner(), + 'publicKey' => $signatory->getPublicKey(), + 'privateKey' => $signatory->getPrivateKey() + ]; + + OC::$server->get(IConfig::class)->setAppValue($app, 'key_pairs', json_encode($signatories)); + } + + + /** + * @param NCSignatory $signatory + */ + public function removeSimpleSignatory(NCSignatory $signatory): void { + $app = $this->setup('app', '', self::$SIGNATORIES_APP); + $signatories = json_decode(OC::$server->get(IConfig::class)->getAppValue($app, 'key_pairs'), true); + if (!is_array($signatories)) { + $signatories = []; + } + + unset($signatories[$signatory->getId()]); + OC::$server->get(IConfig::class)->setAppValue($app, 'key_pairs', json_encode($signatories)); + } +} diff --git a/lib/Tools/Traits/TNCLogger.php b/lib/Tools/Traits/TNCLogger.php new file mode 100644 index 0000000..7b93bf3 --- /dev/null +++ b/lib/Tools/Traits/TNCLogger.php @@ -0,0 +1,201 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use Exception; +use OC; +use OC\HintException; +use Psr\Log\LoggerInterface; +use Throwable; + +trait TNCLogger { + use TNCSetup; + + + public static $EMERGENCY = 4; + public static $ALERT = 3; + public static $CRITICAL = 3; + public static $ERROR = 3; + public static $WARNING = 2; + public static $NOTICE = 1; + public static $INFO = 1; + public static $DEBUG = 0; + + + /** + * @param Throwable $t + * @param array $serializable + */ + public function t(Throwable $t, array $serializable = []): void { + $this->throwable($t, self::$ERROR, $serializable); + } + + /** + * @param Throwable $t + * @param int $level + * @param array $serializable + */ + public function throwable(Throwable $t, int $level = 3, array $serializable = []): void { + $message = ''; + if (!empty($serializable)) { + $message = json_encode($serializable); + } + + $this->logger() + ->log( + $level, + $message, + [ + 'app' => $this->setup('app'), + 'exception' => $t + ] + ); + } + + + /** + * @param Exception $e + * @param array $serializable + */ + public function e(Exception $e, array $serializable = []): void { + $this->exception($e, self::$ERROR, $serializable); + } + + /** + * @param Exception $e + * @param int|array $level + * @param array $serializable + */ + public function exception(Exception $e, $level = 3, array $serializable = []): void { + if (is_array($level) && empty($serializable)) { + $serializable = $level; + $level = 3; + } + + $message = ''; + if (!empty($serializable)) { + $message = json_encode($serializable); + } + + if ($level === self::$DEBUG) { + $level = (int)$this->appConfig('debug_level'); + } + + $this->logger() + ->log( + $level, + $message, + [ + 'app' => $this->setup('app'), + 'exception' => $e + ] + ); + } + + + /** + * @param string $message + * @param bool $trace + * @param array $serializable + */ + public function emergency(string $message, bool $trace = false, array $serializable = []): void { + $this->log(self::$EMERGENCY, '[emergency] ' . $message, $trace, $serializable); + } + + /** + * @param string $message + * @param bool $trace + * @param array $serializable + */ + public function alert(string $message, bool $trace = false, array $serializable = []): void { + $this->log(self::$ALERT, '[alert] ' . $message, $trace, $serializable); + } + + /** + * @param string $message + * @param bool $trace + * @param array $serializable + */ + public function warning(string $message, bool $trace = false, array $serializable = []): void { + $this->log(self::$WARNING, '[warning] ' . $message, $trace, $serializable); + } + + /** + * @param string $message + * @param bool $trace + * @param array $serializable + */ + public function notice(string $message, bool $trace = false, array $serializable = []): void { + $this->log(self::$NOTICE, '[notice] ' . $message, $trace, $serializable); + } + + /** + * @param string $message + * @param array $serializable + */ + public function debug(string $message, array $serializable = []): void { + $message = '[debug] ' . $message; + $debugLevel = (int)$this->appConfig('debug_level'); + $this->log($debugLevel, $message, ($this->appConfig('debug_trace') === '1'), $serializable); + } + + + /** + * @param int $level + * @param string $message + * @param bool $trace + * @param array $serializable + */ + public function log(int $level, string $message, bool $trace = false, array $serializable = []): void { + $opts = ['app' => $this->setup('app')]; + if ($trace) { + $opts['exception'] = new HintException($message, json_encode($serializable)); + } elseif (!empty($serializable)) { + $message .= ' -- ' . json_encode($serializable); + } + + $this->logger() + ->log($level, $message, $opts); + } + + + /** + * @return LoggerInterface + */ + public function logger(): LoggerInterface { + if (isset($this->logger) && $this->logger instanceof LoggerInterface) { + return $this->logger; + } else { + return OC::$server->get(LoggerInterface::class); + } + } +} diff --git a/lib/Tools/Traits/TNCRequest.php b/lib/Tools/Traits/TNCRequest.php new file mode 100644 index 0000000..ffeef21 --- /dev/null +++ b/lib/Tools/Traits/TNCRequest.php @@ -0,0 +1,178 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use OCA\Backup\Tools\Model\NCRequest; +use Exception; +use GuzzleHttp\Exception\ClientException; +use OC; +use OCA\Backup\Tools\Exceptions\RequestNetworkException; +use OCA\Backup\Tools\Model\NCRequestResult; +use OCA\Backup\Tools\Model\Request; +use OCP\Http\Client\IClientService; +use OCP\Http\Client\IResponse; + +trait TNCRequest { + use TNCLogger; + + + /** + * @param int $size + */ + public function setMaxDownloadSize(int $size) { + } + + + /** + * @param NCRequest $request + * + * @return array + * @throws RequestNetworkException + */ + public function retrieveJson(NCRequest $request): array { + $this->doRequest($request); + $requestResult = $request->getResult(); + + return $requestResult->getAsArray(); + } + + + /** + * @param NCRequest $request + * @param bool $exceptionOnIssue + * + * @throws RequestNetworkException + */ + public function doRequest(NCRequest $request, bool $exceptionOnIssue = true): void { + $request->setClient( + $this->clientService() + ->newClient() + ); + + $this->generationClientOptions($request); + + $this->debug('doRequest initiated', ['request' => $request]); + foreach ($request->getProtocols() as $protocol) { + $request->setUsedProtocol($protocol); + try { + $response = $this->useClient($request); + $request->setResult(new NCRequestResult($response)); + break; + } catch (ClientException $e) { + $request->setResult(new NCRequestResult(null, $e)); + } catch (Exception $e) { + $this->exception($e, self::$DEBUG, ['request' => $request]); + } + } + + $this->debug('doRequest done', ['request' => $request]); + + if ($exceptionOnIssue && (!$request->hasResult() || $request->getResult()->hasException())) { + throw new RequestNetworkException(); + } + } + + + /** + * @return IClientService + */ + public function clientService(): IClientService { + if (isset($this->clientService) && $this->clientService instanceof IClientService) { + return $this->clientService; + } else { + return OC::$server->get(IClientService::class); + } + } + + + /** + * @param NCRequest $request + */ + private function generationClientOptions(NCRequest $request) { + $options = [ + 'headers' => $request->getHeaders(), + 'cookies' => $request->getCookies(), + 'verify' => $request->isVerifyPeer(), + 'timeout' => $request->getTimeout(), + 'http_errors' => !$request->isHttpErrorsAllowed() + ]; + + if (!empty($request->getData())) { + $options['body'] = $request->getDataBody(); + } + + if (!empty($request->getParams())) { + $options['form_params'] = $request->getParams(); + } + + if ($request->isLocalAddressAllowed()) { + $options['nextcloud']['allow_local_address'] = true; + } + + if ($request->isFollowLocation()) { + $options['allow_redirects'] = [ + 'max' => 10, + 'strict' => true, + 'referer' => true, + ]; + } else { + $options['allow_redirects'] = false; + } + + $request->setClientOptions($options); + } + + + /** + * @param NCRequest $request + * + * @return IResponse + * @throws Exception + */ + private function useClient(NCRequest $request): IResponse { + $client = $request->getClient(); + switch ($request->getType()) { + case Request::TYPE_POST: + return $client->post($request->getCompleteUrl(), $request->getClientOptions()); + case Request::TYPE_PUT: + return $client->put($request->getCompleteUrl(), $request->getClientOptions()); + case Request::TYPE_DELETE: + return $client->delete($request->getCompleteUrl(), $request->getClientOptions()); + case Request::TYPE_GET: + return $client->get( + $request->getCompleteUrl() . $request->getQueryString(), $request->getClientOptions() + ); + default: + throw new Exception('unknown request type ' . json_encode($request)); + } + } +} diff --git a/lib/Tools/Traits/TNCSetup.php b/lib/Tools/Traits/TNCSetup.php new file mode 100644 index 0000000..7cd6de5 --- /dev/null +++ b/lib/Tools/Traits/TNCSetup.php @@ -0,0 +1,107 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use OC; +use OCP\IConfig; + +trait TNCSetup { + use TArrayTools; + + + /** @var array */ + private $_setup = []; + + + /** + * @param string $key + * @param string $value + * + * @param string $default + * + * @return string + */ + public function setup(string $key, string $value = '', string $default = ''): string { + if ($value !== '') { + $this->_setup[$key] = $value; + } + + return $this->get($key, $this->_setup, $default); + } + + /** + * @param string $key + * @param array $value + * @param array $default + * + * @return array + */ + public function setupArray(string $key, array $value = [], array $default = []): array { + if (!empty($value)) { + $this->_setup[$key] = $value; + } + + return $this->getArray($key, $this->_setup, $default); + } + + /** + * @param string $key + * @param int $value + * @param int $default + * + * @return int + */ + public function setupInt(string $key, int $value = -999, int $default = 0): int { + if ($value !== -999) { + $this->_setup[$key] = $value; + } + + return $this->getInt($key, $this->_setup, $default); + } + + /** + * @param string $key + * + * @return string + */ + public function appConfig(string $key): string { + $app = $this->setup('app'); + if ($app === '') { + return ''; + } + + /** @var IConfig $config */ + $config = OC::$server->get(IConfig::class); + + return $config->getAppValue($app, $key, ''); + } +} diff --git a/lib/Tools/Traits/TNCSignatory.php b/lib/Tools/Traits/TNCSignatory.php new file mode 100644 index 0000000..18b1150 --- /dev/null +++ b/lib/Tools/Traits/TNCSignatory.php @@ -0,0 +1,237 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use OCA\Backup\Tools\Exceptions\InvalidOriginException; +use OCA\Backup\Tools\Exceptions\RequestNetworkException; +use OCA\Backup\Tools\Exceptions\SignatoryException; +use OCA\Backup\Tools\Exceptions\SignatureException; +use OCA\Backup\Tools\ISignedModel; +use OCA\Backup\Tools\Model\NCRequest; +use OCA\Backup\Tools\Model\NCSignatory; + +trait TNCSignatory { + use TNCRequest; + + + /** + * return Signatory by its Id from cache or from direct request. + * Should be overwritten. + * + * @param string $keyId + * @param bool $refresh + * + * @return NCSignatory + * @throws SignatoryException + */ + public function retrieveSignatory(string $keyId, bool $refresh = false): NCSignatory { + if (!$refresh) { + throw new SignatoryException(); + } + + $signatory = new NCSignatory($keyId); + $this->downloadSignatory($signatory, $keyId); + + return $signatory; + } + + + /** + * @param NCSignatory $signatory + * @param string $keyId + * @param array $params + * @param NCRequest|null $request + * + * @throws SignatoryException + */ + public function downloadSignatory( + NCSignatory $signatory, + string $keyId = '', + array $params = [], + ?NCRequest $request = null + ): void { + if (is_null($request)) { + $request = new NCRequest(); + $request->setFollowLocation(true); + $request->setTimeout(5); + } + + $request->basedOnUrl(($keyId !== '') ? $keyId : $signatory->getId()); + $request->setParams($params); + $request->addHeader('Accept', 'application/ld+json'); + + try { + $this->updateSignatory($signatory, $this->retrieveJson($request), $keyId); + } catch (RequestNetworkException $e) { + $this->debug('network issue while downloading Signatory', ['request' => $request]); + throw new SignatoryException('network issue: ' . $e->getMessage()); + } + } + + + /** + * @param NCSignatory $signatory + * @param array $json + * @param string $keyId + * + * @throws SignatoryException + */ + public function updateSignatory(NCSignatory $signatory, array $json, string $keyId = ''): void { + $signatory->setOrigData($json) + ->import($json); + + if ($keyId === '') { + $keyId = $signatory->getKeyId(); + } + + try { + if (($signatory->getId() !== $keyId && $signatory->getKeyId() !== $keyId) + || $signatory->getId() !== $signatory->getKeyOwner() + || $this->getKeyOrigin($signatory->getKeyId()) !== $this->getKeyOrigin($signatory->getId()) + || $signatory->getPublicKey() === '') { + $this->debug('invalid format', ['signatory' => $signatory, 'keyId' => $keyId]); + throw new SignatoryException('invalid format'); + } + } catch (InvalidOriginException $e) { + throw new SignatoryException('invalid origin'); + } + } + + + /** + * @param string $keyId + * + * @return string + * @throws InvalidOriginException + */ + public function getKeyOrigin(string $keyId) { + $host = parse_url($keyId, PHP_URL_HOST); + if (is_string($host) && ($host !== '')) { + return $host; + } + + throw new InvalidOriginException('cannot retrieve origin from ' . $keyId); + } + + + /** + * @param NCSignatory $signatory + * @param string $digest + * @param int $bits + * @param int $type + */ + public function generateKeys( + NCSignatory $signatory, + string $digest = 'rsa', + int $bits = 2048, + int $type = OPENSSL_KEYTYPE_RSA + ) { + $res = openssl_pkey_new( + [ + 'digest_alg' => $digest, + 'private_key_bits' => $bits, + 'private_key_type' => $type, + ] + ); + + openssl_pkey_export($res, $privateKey); + $publicKey = openssl_pkey_get_details($res)['key']; + + $signatory->setPublicKey($publicKey); + $signatory->setPrivateKey($privateKey); + } + + + /** + * @param string $clear + * @param NCSignatory $signatory + * + * @return string + * @throws SignatoryException + */ + public function signString(string $clear, NCSignatory $signatory): string { + $privateKey = $signatory->getPrivateKey(); + if ($privateKey === '') { + throw new SignatoryException('empty private key'); + } + + openssl_sign($clear, $signed, $privateKey, $this->getOpenSSLAlgo($signatory)); + + return base64_encode($signed); + } + + + /** + * @param ISignedModel $model + * @param NCSignatory $signatory + * + * @throws SignatoryException + */ + public function signModel(ISignedModel $model, NCSignatory $signatory): void { + $string = json_encode($model->signedData()); + $signature = $this->signString($string, $signatory); + $model->setSignature($signature); + } + + + /** + * @param string $clear + * @param string $signed + * @param string $publicKey + * @param string $algo + * + * @throws SignatureException + */ + public function verifyString( + string $clear, string $signed, string $publicKey, string $algo = NCSignatory::SHA256 + ) { + if (openssl_verify($clear, $signed, $publicKey, $algo) !== 1) { + throw new SignatureException('signature issue'); + } + } + + /** + * @param ISignedModel $model + * @param string $publicKey + * @param string $algo + * + * @throws SignatureException + */ + public function verifyModel( + ISignedModel $model, + string $publicKey, + string $algo = NCSignatory::SHA256 + ): void { + $string = json_encode($model->signedData()); + $this->verifyString($string, $model->getSignature(), $publicKey, $algo); + } +} diff --git a/lib/Tools/Traits/TNCWellKnown.php b/lib/Tools/Traits/TNCWellKnown.php new file mode 100644 index 0000000..d51ade5 --- /dev/null +++ b/lib/Tools/Traits/TNCWellKnown.php @@ -0,0 +1,128 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use OCA\Backup\Tools\Exceptions\RequestNetworkException; +use OCA\Backup\Tools\Exceptions\WellKnownLinkNotFoundException; +use OCA\Backup\Tools\Model\NCRequest; +use OCA\Backup\Tools\Model\NCWebfinger; +use OCA\Backup\Tools\Model\NCWellKnownLink; +use OCA\Backup\Tools\Model\SimpleDataStore; + +trait TNCWellKnown { + use TNCRequest; + + public static $WEBFINGER = '/.well-known/webfinger'; + + + /** + * @param string $host + * @param string $subject + * @param string $rel + * + * @return SimpleDataStore + * @throws RequestNetworkException + * @throws WellKnownLinkNotFoundException + */ + public function getResourceData(string $host, string $subject, string $rel): SimpleDataStore { + $link = $this->getLink($host, $subject, $rel); + + $request = new NCRequest(''); + $request->basedOnUrl($link->getHref()); + $request->addHeader('Accept', $link->getType()); + $request->setFollowLocation(true); + $request->setLocalAddressAllowed(true); + $request->setTimeout(5); + $data = $this->retrieveJson($request); + + return new SimpleDataStore($data); + } + + + /** + * @param string $host + * @param string $subject + * @param string $rel + * + * @return NCWellKnownLink + * @throws RequestNetworkException + * @throws WellKnownLinkNotFoundException + */ + public function getLink(string $host, string $subject, string $rel): NCWellKnownLink { + return $this->extractLink($rel, $this->getWebfinger($host, $subject)); + } + + + /** + * @param string $host + * @param string $subject + * @param string $rel + * + * @return NCWebfinger + * @throws RequestNetworkException + */ + public function getWebfinger(string $host, string $subject, string $rel = ''): NCWebfinger { + $request = new NCRequest(self::$WEBFINGER); + $request->setHost($host); + $request->setProtocols(['https', 'http']); + $request->setFollowLocation(true); + $request->setLocalAddressAllowed(true); + $request->setTimeout(5); + + $request->addParam('resource', $subject); + if ($rel !== '') { + $request->addParam('rel', $rel); + } + + $result = $this->retrieveJson($request); + + return new NCWebfinger($result); + } + + + /** + * @param string $rel + * @param NCWebfinger $webfinger + * + * @return NCWellKnownLink + * @throws WellKnownLinkNotFoundException + */ + public function extractLink(string $rel, NCWebfinger $webfinger): NCWellKnownLink { + foreach ($webfinger->getLinks() as $link) { + if ($link->getRel() === $rel) { + return $link; + } + } + + throw new WellKnownLinkNotFoundException(); + } +} diff --git a/lib/Tools/Traits/TStringTools.php b/lib/Tools/Traits/TStringTools.php new file mode 100644 index 0000000..ad6648c --- /dev/null +++ b/lib/Tools/Traits/TStringTools.php @@ -0,0 +1,258 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Backup now. Restore later. + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2022 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Backup\Tools\Traits; + +use DateTime; +use Exception; + +trait TStringTools { + use TArrayTools; + + + /** + * @param int $length + * + * @return string + */ + protected function token(int $length = 15): string { + $chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890'; + + $str = ''; + $max = strlen($chars); + for ($i = 0; $i < $length; $i++) { + try { + $str .= $chars[random_int(0, $max - 2)]; + } catch (Exception $e) { + } + } + + return $str; + } + + + /** + * Generate uuid: 2b5a7a87-8db1-445f-a17b-405790f91c80 + * + * @param int $length + * + * @return string + */ + protected function uuid(int $length = 0): string { + $uuid = sprintf( + '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, + mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) + ); + + if ($length > 0) { + if ($length <= 16) { + $uuid = str_replace('-', '', $uuid); + } + + $uuid = substr($uuid, 0, $length); + } + + return $uuid; + } + + + /** + * @param string $line + * @param int $length + * + * @return string + */ + protected function cut(string $line, int $length): string { + if (strlen($line) < $length) { + return $line; + } + + return substr($line, 0, $length - 5) . ' (..)'; + } + + /** + * @param string $str1 + * @param string $str2 + * @param bool $cs case sensitive ? + * + * @return string + */ + protected function commonPart(string $str1, string $str2, bool $cs = true): string { + for ($i = 0; $i < strlen($str1) && $i < strlen($str2); $i++) { + $chr1 = $str1[$i]; + $chr2 = $str2[$i]; + + if (!$cs) { + $chr1 = strtolower($chr1); + $chr2 = strtolower($chr2); + } + + if ($chr1 !== $chr2) { + break; + } + } + + return substr($str1, 0, $i); + } + + + /** + * @param string $line + * @param array $params + * + * @return string + */ + protected function feedStringWithParams(string $line, array $params): string { + $ak = array_keys($params); + foreach ($ak as $k) { + $line = str_replace('{' . $k . '}', (string)$params[$k], $line); + } + + return $line; + } + + + /** + * @param int $words + * + * @return string + */ + public function generateRandomSentence(int $words = 5): string { + $sentence = []; + for ($i = 0; $i < $words; $i++) { + $sentence[] = $this->generateRandomWord(rand(2, 12)); + } + + return implode(' ', $sentence); + } + + + /** + * @param int $length + * + * @return string + */ + public function generateRandomWord(int $length = 8): string { + $c = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v']; + $v = ['a', 'e', 'i', 'o', 'u', 'y']; + + $word = []; + for ($i = 0; $i <= ($length / 2); $i++) { + $word[] = $c[array_rand($c)]; + $word[] = $v[array_rand($v)]; + } + + return implode('', $word); + } + + + /** + * @param int $bytes + * + * @return string + */ + public function humanReadable(int $bytes): string { + if ($bytes == 0) { + return '0.00 B'; + } + + $s = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; + $e = floor(log($bytes, 1024)); + + return round($bytes / pow(1024, $e), 2) . ' ' . $s[$e]; + } + + + /** + * @param int $first + * @param int $second + * @param bool $short + * + * @return string + * @throws Exception + */ + public function getDateDiff( + int $first, + int $second = 0, + bool $short = false, + array $words = [] + ): string { + if ($second === 0) { + $first = time() - $first; + $second = time(); + } + + $f = new DateTime('@' . $first); + $s = new DateTime('@' . $second); + $duration = $second - $first; + if ($short) { + $minutes = $this->get('minutes', $words, 'M'); + $hours = $this->get('hours', $words, 'H'); + $days = $this->get('days', $words, 'D'); + + if ($duration < 60) { + return $f->diff($s)->format('<1' . $minutes); + } + if ($duration < 3600) { + return $f->diff($s)->format('%i' . $minutes); + } + if ($duration < 86400) { + return $f->diff($s)->format('%h' . $hours . ', %i' . $minutes); + } + + return $f->diff($s)->format('%a' . $days . ', %h' . $hours . ', %i' . $minutes); + } + + $seconds = $this->get('seconds', $words, 'seconds'); + $minutes = $this->get('minutes', $words, 'minutes'); + $hours = $this->get('hours', $words, 'hours'); + $days = $this->get('days', $words, 'days'); + if ($duration < 60) { + return $f->diff($s)->format('%s ' . $seconds); + } + + if ($duration < 3600) { + return $f->diff($s)->format('%i ' . $minutes . ' and %s ' . $seconds); + } + + if ($duration < 86400) { + return $f->diff($s)->format('%h ' . $hours . ', %i ' . $minutes . ' and %s ' . $seconds); + } + + return $f->diff($s)->format( + '%a ' . $days . + ', %h ' . $hours . + ', %i ' . $minutes . + ' and %s ' . $seconds + ); + } +} diff --git a/lib/Wrappers/AppDataRootWrapper.php b/lib/Wrappers/AppDataRootWrapper.php index 1017da0..2808fce 100644 --- a/lib/Wrappers/AppDataRootWrapper.php +++ b/lib/Wrappers/AppDataRootWrapper.php @@ -31,6 +31,7 @@ declare(strict_types=1); namespace OCA\Backup\Wrappers; +use OC; use OC\Config; use OC\Files\Node\File; use OC\Files\Node\Folder; @@ -45,6 +46,7 @@ use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFolder; use OCP\Files\SimpleFS\ISimpleRoot; use OCP\IConfig; +use RuntimeException; /** * Class AppDataRootWrapper @@ -158,7 +160,7 @@ class AppDataRootWrapper { public function getRoot(): Folder { if ($this->isSimpleRoot()) { /** @var IRootFolder $rootFolder */ - $rootFolder = \OC::$server->get(IRootFolder::class); + $rootFolder = OC::$server->get(IRootFolder::class); $root = $rootFolder->get($this->getAppDataPath()); } else { $root = $this->getExternalFolder()->getRootFolder(); @@ -265,10 +267,10 @@ class AppDataRootWrapper { */ private function getAppDataPath(): string { /** @var Config $config */ - $config = \OC::$server->get(IConfig::class); + $config = OC::$server->get(IConfig::class); $instanceId = $config->getSystemValue('instanceid', null); if ($instanceId === null) { - throw new \RuntimeException('no instance id!'); + throw new RuntimeException('no instance id!'); } return 'appdata_' . $instanceId . '/' . Application::APP_ID; diff --git a/restore.php b/restore.php index c93aba1..f7c1777 100644 --- a/restore.php +++ b/restore.php @@ -32,12 +32,9 @@ declare(strict_types=1); namespace OCA\Backup; use Composer\Autoload\ClassLoader; -use ArtificialOwl\MySmallPhpTools\DI\DIContainer; -use ArtificialOwl\MySmallPhpTools\Exceptions\DependencyInjectionException; use Exception; use OC\Config; use OC\Logger; -use OCA\Backup\Model\Backup; use OCA\Backup\Service\PointService; use OCP\IConfig; use OCP\ILogger; |