Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/backup.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2022-07-14 14:30:08 +0300
committerGitHub <noreply@github.com>2022-07-14 14:30:08 +0300
commitcabb922fdef6a6907242ceaf4d723d4dc54d9681 (patch)
treec6ffba849d133a08424136cf9972a50f73f11ef8
parent8e9a634009dbf071afaa3973755bc78ad34a1f45 (diff)
parent9b8c5d2037ce4fdb2c0c5f8aeed3ac2a9e33b257 (diff)
Merge pull request #360 from nextcloud/backport/300/stable24v1.1.0v.1.1.0
[stable24] get rid of mspt
-rwxr-xr-xappinfo/info.xml4
-rwxr-xr-xappinfo/routes.php18
-rw-r--r--composer.json1
-rw-r--r--composer.lock263
-rw-r--r--lib/Activity/Provider.php4
-rwxr-xr-xlib/AppInfo/Application.php2
-rwxr-xr-xlib/Command/ExternalAppData.php4
-rwxr-xr-xlib/Command/FileSearch.php10
-rwxr-xr-xlib/Command/PointArchive.php2
-rwxr-xr-xlib/Command/PointComment.php2
-rwxr-xr-xlib/Command/PointCreate.php2
-rwxr-xr-xlib/Command/PointDelete.php10
-rwxr-xr-xlib/Command/PointDetails.php4
-rwxr-xr-xlib/Command/PointDownload.php8
-rwxr-xr-xlib/Command/PointHistory.php4
-rwxr-xr-xlib/Command/PointList.php18
-rwxr-xr-xlib/Command/PointRestore.php20
-rwxr-xr-xlib/Command/PointScan.php4
-rwxr-xr-xlib/Command/PointUnarchive.php2
-rwxr-xr-xlib/Command/PointUnpack.php2
-rwxr-xr-xlib/Command/PointUpload.php7
-rwxr-xr-xlib/Command/RemoteAdd.php346
-rwxr-xr-xlib/Command/RemoteList.php146
-rwxr-xr-xlib/Command/RemoteRemove.php115
-rwxr-xr-xlib/Command/Reset.php2
-rwxr-xr-xlib/Command/SetupImport.php6
-rwxr-xr-xlib/Controller/LocalController.php14
-rwxr-xr-xlib/Controller/RemoteController.php419
-rw-r--r--lib/Cron/Backup.php4
-rw-r--r--lib/Cron/Event.php2
-rw-r--r--lib/Db/ChangesRequestBuilder.php6
-rw-r--r--lib/Db/CoreQueryBuilder.php4
-rw-r--r--lib/Db/EventRequestBuilder.php6
-rw-r--r--lib/Db/ExternalFolderRequestBuilder.php6
-rw-r--r--lib/Db/PointRequestBuilder.php6
-rw-r--r--lib/Db/RemoteRequest.php1
-rw-r--r--lib/Db/RemoteRequestBuilder.php6
-rw-r--r--lib/Db/RestoringDataRequestBuilder.php6
-rw-r--r--lib/Handlers/WebfingerHandler.php4
-rw-r--r--lib/IRemoteRequest.php10
-rw-r--r--lib/Listeners/NodeEvent.php4
-rw-r--r--lib/Model/ArchiveFile.php4
-rw-r--r--lib/Model/BackupEvent.php12
-rw-r--r--lib/Model/ChangedFile.php10
-rw-r--r--lib/Model/ChunkPartHealth.php4
-rw-r--r--lib/Model/ExternalFolder.php14
-rw-r--r--lib/Model/RemoteInstance.php20
-rw-r--r--lib/Model/RestoringChunk.php10
-rw-r--r--lib/Model/RestoringChunkPart.php6
-rw-r--r--lib/Model/RestoringData.php10
-rw-r--r--lib/Model/RestoringHealth.php14
-rw-r--r--lib/Model/RestoringPoint.php26
-rw-r--r--lib/RemoteRequest/CoreRequest.php14
-rw-r--r--lib/RemoteRequest/CreateRestoringPoint.php12
-rw-r--r--lib/RemoteRequest/DeleteRestoringPoint.php10
-rw-r--r--lib/RemoteRequest/DownloadRestoringChunk.php12
-rw-r--r--lib/RemoteRequest/GetRestoringPoint.php10
-rw-r--r--lib/RemoteRequest/ListRestoringPoint.php6
-rw-r--r--lib/RemoteRequest/UpdateRestoringPoint.php14
-rw-r--r--lib/RemoteRequest/UploadRestoringChunk.php12
-rw-r--r--lib/Service/ChunkService.php22
-rw-r--r--lib/Service/ConfigService.php10
-rw-r--r--lib/Service/CronService.php2
-rw-r--r--lib/Service/EncryptService.php2
-rw-r--r--lib/Service/ExportService.php2
-rw-r--r--lib/Service/ExternalFolderService.php43
-rw-r--r--lib/Service/FilesService.php18
-rw-r--r--lib/Service/OccService.php2
-rw-r--r--lib/Service/OutputService.php2
-rw-r--r--lib/Service/PackService.php10
-rw-r--r--lib/Service/PointService.php20
-rw-r--r--lib/Service/RemoteService.php38
-rw-r--r--lib/Service/RemoteStreamService.php52
-rw-r--r--lib/Service/RestoreService.php6
-rw-r--r--lib/Service/UploadService.php42
-rw-r--r--lib/SqlDump/SqlDumpMySQL.php2
-rw-r--r--lib/SqlDump/SqlDumpPgSQL.php2
-rw-r--r--lib/Tools/ActivityPub/NCSignature.php413
-rw-r--r--lib/Tools/Db/ExtendedQueryBuilder.php1135
-rw-r--r--lib/Tools/Db/IQueryRow.php49
-rw-r--r--lib/Tools/Exceptions/ArrayNotFoundException.php42
-rw-r--r--lib/Tools/Exceptions/DateTimeException.php42
-rw-r--r--lib/Tools/Exceptions/InvalidItemException.php42
-rw-r--r--lib/Tools/Exceptions/InvalidOriginException.php42
-rw-r--r--lib/Tools/Exceptions/ItemNotFoundException.php42
-rw-r--r--lib/Tools/Exceptions/JsonNotRequestedException.php42
-rw-r--r--lib/Tools/Exceptions/MalformedArrayException.php42
-rw-r--r--lib/Tools/Exceptions/RequestContentException.php42
-rw-r--r--lib/Tools/Exceptions/RequestNetworkException.php42
-rw-r--r--lib/Tools/Exceptions/RequestResultNotJsonException.php42
-rw-r--r--lib/Tools/Exceptions/RequestResultSizeException.php42
-rw-r--r--lib/Tools/Exceptions/RequestServerException.php42
-rw-r--r--lib/Tools/Exceptions/RowNotFoundException.php42
-rw-r--r--lib/Tools/Exceptions/SignatoryException.php42
-rw-r--r--lib/Tools/Exceptions/SignatureException.php42
-rw-r--r--lib/Tools/Exceptions/UnknownTypeException.php42
-rw-r--r--lib/Tools/Exceptions/WellKnownLinkNotFoundException.php42
-rw-r--r--lib/Tools/IDeserializable.php42
-rw-r--r--lib/Tools/ISignedModel.php55
-rw-r--r--lib/Tools/Model/NCRequest.php174
-rw-r--r--lib/Tools/Model/NCRequestResult.php321
-rw-r--r--lib/Tools/Model/NCSignatory.php294
-rw-r--r--lib/Tools/Model/NCSignedRequest.php348
-rw-r--r--lib/Tools/Model/NCWebfinger.php197
-rw-r--r--lib/Tools/Model/NCWellKnownLink.php222
-rw-r--r--lib/Tools/Model/Request.php832
-rw-r--r--lib/Tools/Model/SimpleDataStore.php487
-rw-r--r--lib/Tools/Model/TreeNode.php232
-rw-r--r--lib/Tools/Traits/TArrayTools.php432
-rw-r--r--lib/Tools/Traits/TAsync.php75
-rw-r--r--lib/Tools/Traits/TConsoleTree.php143
-rw-r--r--lib/Tools/Traits/TDeserialize.php143
-rw-r--r--lib/Tools/Traits/TFileTools.php47
-rw-r--r--lib/Tools/Traits/TNCController.php113
-rw-r--r--lib/Tools/Traits/TNCLocalSignatory.php111
-rw-r--r--lib/Tools/Traits/TNCLogger.php201
-rw-r--r--lib/Tools/Traits/TNCRequest.php178
-rw-r--r--lib/Tools/Traits/TNCSetup.php107
-rw-r--r--lib/Tools/Traits/TNCSignatory.php237
-rw-r--r--lib/Tools/Traits/TNCWellKnown.php128
-rw-r--r--lib/Tools/Traits/TStringTools.php258
-rw-r--r--lib/Wrappers/AppDataRootWrapper.php8
-rw-r--r--restore.php3
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;