From 05f24c8591b43fb09cbb1046a9e3069a3d185694 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:27:22 +0200 Subject: [PATCH 01/91] Setting up notification channels. --- solid/lib/Controller/CalendarController.php | 7 ++- solid/lib/Controller/ContactsController.php | 7 ++- solid/lib/Controller/ProfileController.php | 7 ++- solid/lib/Controller/StorageController.php | 6 +- .../lib/Notifications/SolidNotifications.php | 24 ++++++++ solid/lib/Notifications/SolidPubSub.php | 29 ++++++++++ solid/lib/Notifications/SolidWebHook.php | 56 +++++++++++++++++++ 7 files changed, 125 insertions(+), 11 deletions(-) create mode 100644 solid/lib/Notifications/SolidNotifications.php create mode 100644 solid/lib/Notifications/SolidPubSub.php create mode 100644 solid/lib/Notifications/SolidWebHook.php diff --git a/solid/lib/Controller/CalendarController.php b/solid/lib/Controller/CalendarController.php index 3a4c4054..7cd59b7f 100644 --- a/solid/lib/Controller/CalendarController.php +++ b/solid/lib/Controller/CalendarController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -118,15 +119,15 @@ public function handleRequest($userId, $path) { $this->filesystem = $this->getFileSystem($userId); $this->resourceServer = new ResourceServer($this->filesystem, $this->response); - $this->WAC = new WAC($this->filesystem); + $this->WAC = new WAC($this->filesystem); $this->DPop = new DPop(); $request = $this->rawRequest; $baseUrl = $this->getCalendarUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notification); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ContactsController.php b/solid/lib/Controller/ContactsController.php index cb95cf5b..1f4359b4 100644 --- a/solid/lib/Controller/ContactsController.php +++ b/solid/lib/Controller/ContactsController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -118,15 +119,15 @@ public function handleRequest($userId, $path) { $this->filesystem = $this->getFileSystem($userId); $this->resourceServer = new ResourceServer($this->filesystem, $this->response); - $this->WAC = new WAC($this->filesystem); + $this->WAC = new WAC($this->filesystem); $this->DPop = new DPop(); $request = $this->rawRequest; $baseUrl = $this->getContactsUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notification); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ProfileController.php b/solid/lib/Controller/ProfileController.php index 7d64f6f9..caec62ef 100644 --- a/solid/lib/Controller/ProfileController.php +++ b/solid/lib/Controller/ProfileController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -135,15 +136,15 @@ public function handleRequest($userId, $path) { $this->filesystem = $this->getFileSystem($userId); $this->resourceServer = new ResourceServer($this->filesystem, $this->response); - $this->WAC = new WAC($this->filesystem); + $this->WAC = new WAC($this->filesystem); $this->DPop = new DPop(); $request = $this->rawRequest; $baseUrl = $this->getProfileUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notification); if ($request->getHeaderLine("DPop")) { try { diff --git a/solid/lib/Controller/StorageController.php b/solid/lib/Controller/StorageController.php index 3f7fd16d..9cb5b234 100644 --- a/solid/lib/Controller/StorageController.php +++ b/solid/lib/Controller/StorageController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -287,8 +288,9 @@ public function handleRequest($userId, $path) { $baseUrl = $this->getStorageUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notifications); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Notifications/SolidNotifications.php b/solid/lib/Notifications/SolidNotifications.php new file mode 100644 index 00000000..9fb640e8 --- /dev/null +++ b/solid/lib/Notifications/SolidNotifications.php @@ -0,0 +1,24 @@ +notifications = [ + new SolidWebhook(), + new SolidPubSub($pubsub) + ]; + } + + public function send($path, $type) { + foreach ($this->notifications as $notification) { + $notification->send($path, $type); + } + } + } \ No newline at end of file diff --git a/solid/lib/Notifications/SolidPubSub.php b/solid/lib/Notifications/SolidPubSub.php new file mode 100644 index 00000000..081e6f81 --- /dev/null +++ b/solid/lib/Notifications/SolidPubSub.php @@ -0,0 +1,29 @@ +pubsub = $pubsubUrl; + } + + public function send($path, $type) { + $pubsub = str_replace(["https://", "http://"], "ws://", $this->pubsub); + + $client = new Client($pubsub, array( + 'headers' => array( + 'Sec-WebSocket-Protocol' => 'solid-0.1' + ) + )); + + try { + $client->send("pub $path\n"); + } catch (\WebSocket\Exception $exception) { + throw new Exception('Could not write to pubsub server', 502, $exception); + } + } + } \ No newline at end of file diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php new file mode 100644 index 00000000..79a82ef5 --- /dev/null +++ b/solid/lib/Notifications/SolidWebHook.php @@ -0,0 +1,56 @@ +getSubscribedUrls($path, $type); + foreach ($subscribedUrls as $url) { + $this->postUpdate($url, $path, $type); + } + } + private function getSubscribedUrls($path, $type) { + } + private function postUpdate($url, $path, $type) { + try { + $postData = $this->createUpdatePayload($path, $type); + $opts = array('http' => + array( + 'method' => 'POST', + 'header' => 'Content-Type: application/ld+json', + 'content' => $postData + ) + ); + $context = stream_context_create($opts); + $result = file_get_contents($webhook, false, $context); + } catch (\Exception $exception) { + throw new Exception('Could not write to webhook server', 502, $exception); + } + } + private function createUpdatePayload($path, $type) { + //$updateId = "urn:uuid:"; + //$actor = ""; + $object = [ + "id" => $path, + "type" => [ + "http://www.w3.org/ns/ldp#Resource" + ] + ]; + $state = "1234-5678-90ab-cdef-12345678"; + $published = date(DATE_ISO8601); + $payload = [ + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://www.w3.org/ns/solid/notification/v1" + ], + // "id":$updateId, + // "actor" : [$actor], + "type" => [$type], + "object" => $object, + // "state" : $state + "published" => $published + ]; + + return json_encode($payload); + } + } \ No newline at end of file From 2e7dfbb584a96881add380810e907ee30d934da2 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:28:49 +0200 Subject: [PATCH 02/91] fix return type --- solid/lib/Notifications/SolidWebHook.php | 1 + 1 file changed, 1 insertion(+) diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php index 79a82ef5..225a8b85 100644 --- a/solid/lib/Notifications/SolidWebHook.php +++ b/solid/lib/Notifications/SolidWebHook.php @@ -10,6 +10,7 @@ public function send($path, $type) { } } private function getSubscribedUrls($path, $type) { + return []; // FIXME: Read this from the subscriptions } private function postUpdate($url, $path, $type) { try { From 0079b8bec201a069b69d4ab7eae78e0d86a59fac Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:36:10 +0200 Subject: [PATCH 03/91] add TODO list for what needs to be done for this feature to be complete --- solid/TODO.Notifications | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 solid/TODO.Notifications diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications new file mode 100644 index 00000000..eaaf6669 --- /dev/null +++ b/solid/TODO.Notifications @@ -0,0 +1,9 @@ +- [ ] advertise the notifications channel in well-known +- [ ] advertise the notifications channel in HTTP headers +- [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud +- [ ] add notifications controller +- [ ] handle register requests - this must validate that the requestor has read access to the resource; +- [ ] handle unregister requests +- [ ] implement function to get subscription in SolidWebHook +- [ ] add actor to notifications +- [ ] add UUID to notifications From c654aeb0a189291069591fd96dfc176a09b4dd90 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:50:57 +0200 Subject: [PATCH 04/91] update todo --- solid/TODO.Notifications | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications index eaaf6669..9af93c0b 100644 --- a/solid/TODO.Notifications +++ b/solid/TODO.Notifications @@ -2,8 +2,14 @@ - [ ] advertise the notifications channel in HTTP headers - [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud - [ ] add notifications controller +- [ ] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry + - [ ] handle register requests - this must validate that the requestor has read access to the resource; -- [ ] handle unregister requests +- [ ] handle unregister requests - only the webid that subscribed should be able to unsubscribe - [ ] implement function to get subscription in SolidWebHook - [ ] add actor to notifications - [ ] add UUID to notifications + +- [ ] Add support for the rate limit feature. +- [ ] create a solid-notifications-lastsent database table - columns are subscription_id and lastsent; +- [ ] how can we stop sending notifications when read access was revoked? From 1559a3d8bea70886464b47318c62b99396dc02d6 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:53:11 +0200 Subject: [PATCH 05/91] use dev branch --- solid/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/composer.json b/solid/composer.json index 3cef351f..42617404 100644 --- a/solid/composer.json +++ b/solid/composer.json @@ -30,7 +30,7 @@ "pdsinterop/flysystem-nextcloud":"^0.2", "pdsinterop/flysystem-rdf": "^0.5", "pdsinterop/solid-auth": "^0.7", - "pdsinterop/solid-crud": "^0.6", + "pdsinterop/solid-crud": "dev-feature/notificationsInterface", "psr/log" : "^1.1" }, "require-dev": { From 625cdb59b811f80b88b20d4d5a07b0811409017f Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 16:47:10 +0200 Subject: [PATCH 06/91] update composer.lock --- solid/composer.lock | 150 +++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 73 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index 876aaff9..4c9ccf3c 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5d63fb5c291e8f16e3e0b5cd42de117c", + "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", "packages": [ { "name": "arc/base", @@ -433,25 +433,24 @@ }, { "name": "laminas/laminas-diactoros", - "version": "2.14.0", + "version": "2.17.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28" + "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6cb35f61913f06b2c91075db00f67cfd78869e28", - "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", + "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", "shasum": "" }, "require": { - "php": "^7.3 || ~8.0.0 || ~8.1.0", + "php": "^7.4 || ~8.0.0 || ~8.1.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0" }, "conflict": { - "phpspec/prophecy": "<1.9.0", "zendframework/zend-diactoros": "*" }, "provide": { @@ -464,10 +463,9 @@ "ext-gd": "*", "ext-libxml": "*", "http-interop/http-factory-tests": "^0.9.0", - "laminas/laminas-coding-standard": "~2.3.0", + "laminas/laminas-coding-standard": "^2.4.0", "php-http/psr7-integration-tests": "^1.1.1", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^9.5.23", "psalm/plugin-phpunit": "^0.17.0", "vimeo/psalm": "^4.24.0" }, @@ -528,7 +526,7 @@ "type": "community_bridge" } ], - "time": "2022-07-28T12:23:48+00:00" + "time": "2022-08-30T17:01:46+00:00" }, { "name": "lcobucci/clock", @@ -1010,37 +1008,38 @@ }, { "name": "league/uri", - "version": "6.7.1", + "version": "6.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea" + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", - "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/a700b4656e4c54371b799ac61e300ab25a2d1d39", + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39", "shasum": "" }, "require": { "ext-json": "*", "league/uri-interfaces": "^2.3", - "php": "^7.4 || ^8.0", - "psr/http-message": "^1.0" + "php": "^8.1", + "psr/http-message": "^1.0.1" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^v3.3.2", - "nyholm/psr7": "^1.5", - "php-http/psr7-integration-tests": "^1.1", - "phpstan/phpstan": "^1.2.0", + "friendsofphp/php-cs-fixer": "^v3.9.5", + "nyholm/psr7": "^1.5.1", + "php-http/psr7-integration-tests": "^1.1.1", + "phpbench/phpbench": "^1.2.6", + "phpstan/phpstan": "^1.8.5", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpunit/phpunit": "^9.5.10", - "psr/http-factory": "^1.0" + "phpstan/phpstan-phpunit": "^1.1.1", + "phpstan/phpstan-strict-rules": "^1.4.3", + "phpunit/phpunit": "^9.5.24", + "psr/http-factory": "^1.0.1" }, "suggest": { "ext-fileinfo": "Needed to create Data URI from a filepath", @@ -1097,7 +1096,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.7.1" + "source": "https://github.com/thephpleague/uri/tree/6.8.0" }, "funding": [ { @@ -1105,7 +1104,7 @@ "type": "github" } ], - "time": "2022-06-29T09:48:18+00:00" + "time": "2022-09-13T19:58:47+00:00" }, { "name": "league/uri-interfaces", @@ -1537,16 +1536,16 @@ }, { "name": "pdsinterop/solid-crud", - "version": "v0.6.0", + "version": "dev-feature/notificationsInterface", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474" + "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/d68164b50b6b575a7f634aa87374fba3ef84a838", + "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838", "shasum": "" }, "require": { @@ -1561,6 +1560,9 @@ "psr/http-message": "^1.0", "textalk/websocket": "^1.5" }, + "require-dev": { + "phpunit/phpunit": "^9" + }, "type": "library", "autoload": { "psr-4": { @@ -1574,9 +1576,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.6.0" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" }, - "time": "2022-08-24T08:13:54+00:00" + "time": "2022-09-16T13:37:05+00:00" }, { "name": "pietercolpaert/hardf", @@ -2263,16 +2265,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -2313,9 +2315,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" }, - "time": "2022-05-31T20:59:12+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "phar-io/manifest", @@ -2430,16 +2432,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.16", + "version": "9.2.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", "shasum": "" }, "require": { @@ -2495,7 +2497,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" }, "funding": [ { @@ -2503,7 +2505,7 @@ "type": "github" } ], - "time": "2022-08-20T05:26:47+00:00" + "time": "2022-08-30T12:24:04+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2748,16 +2750,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.23", + "version": "9.5.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34" + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", "shasum": "" }, "require": { @@ -2786,7 +2788,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.1", "sebastian/version": "^3.0.2" }, "suggest": { @@ -2830,7 +2832,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" }, "funding": [ { @@ -2842,7 +2844,7 @@ "type": "github" } ], - "time": "2022-08-22T14:01:36+00:00" + "time": "2022-08-30T07:42:16+00:00" }, { "name": "sebastian/cli-parser", @@ -3013,16 +3015,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -3075,7 +3077,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -3083,7 +3085,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -3273,16 +3275,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -3338,7 +3340,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -3346,7 +3348,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -3701,16 +3703,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", "shasum": "" }, "require": { @@ -3722,7 +3724,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3745,7 +3747,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" }, "funding": [ { @@ -3753,7 +3755,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2022-09-12T14:47:03+00:00" }, { "name": "sebastian/version", @@ -3861,7 +3863,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "pdsinterop/solid-crud": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3870,5 +3874,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.1.0" } From 87a99552fe3604cae2792d052621b668aac18299 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 16:47:51 +0200 Subject: [PATCH 07/91] whitespace fix --- solid/lib/Notifications/SolidNotifications.php | 2 +- solid/lib/Notifications/SolidPubSub.php | 2 +- solid/lib/Notifications/SolidWebHook.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/lib/Notifications/SolidNotifications.php b/solid/lib/Notifications/SolidNotifications.php index 9fb640e8..dac12069 100644 --- a/solid/lib/Notifications/SolidNotifications.php +++ b/solid/lib/Notifications/SolidNotifications.php @@ -21,4 +21,4 @@ public function send($path, $type) { $notification->send($path, $type); } } - } \ No newline at end of file + } diff --git a/solid/lib/Notifications/SolidPubSub.php b/solid/lib/Notifications/SolidPubSub.php index 081e6f81..07291cf5 100644 --- a/solid/lib/Notifications/SolidPubSub.php +++ b/solid/lib/Notifications/SolidPubSub.php @@ -26,4 +26,4 @@ public function send($path, $type) { throw new Exception('Could not write to pubsub server', 502, $exception); } } - } \ No newline at end of file + } diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php index 225a8b85..d379bb5f 100644 --- a/solid/lib/Notifications/SolidWebHook.php +++ b/solid/lib/Notifications/SolidWebHook.php @@ -54,4 +54,4 @@ private function createUpdatePayload($path, $type) { return json_encode($payload); } - } \ No newline at end of file + } From 4564fa93cbf6ff18dbb3f53b23400e371a6501dd Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:11:46 +0200 Subject: [PATCH 08/91] add database schema for webhook registration --- .../Version000000Date20220919084800.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 solid/lib/Migration/Version000000Date20220919084800.php diff --git a/solid/lib/Migration/Version000000Date20220919084800.php b/solid/lib/Migration/Version000000Date20220919084800.php new file mode 100644 index 00000000..82d71197 --- /dev/null +++ b/solid/lib/Migration/Version000000Date20220919084800.php @@ -0,0 +1,54 @@ +hasTable('solid_notifications_webhooks')) { + $table = $schema->createTable('solid_notifications_webhooks'); + // id, webid, path, url, expiry + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + ]); + $table->addColumn('webid', 'string', [ + 'notnull' => true, + 'length' => 2048 + ]); + $table->addColumn('path', 'string', [ + 'notnull' => true, + 'length' => 2048, + ]); + $table->addColumn('url', 'string', [ + 'notnull' => true, + 'length' => 2048, + ]); + $table->addColumn('expiry', 'string', [ + 'notnull' => true, + 'length' => 2048, + ]); + + $table->setPrimaryKey(['id']); + $table->addIndex(['webid'], 'solid_notifications_webhooks_webid_index'); + $table->addIndex(['path'], 'solid_notifications_webhooks_path_index'); + } + return $schema; + } +} From 943182c57ddac8e994b2dedb0097be27ab149624 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:39:38 +0200 Subject: [PATCH 09/91] typofix --- solid/lib/Controller/CalendarController.php | 2 +- solid/lib/Controller/ContactsController.php | 2 +- solid/lib/Controller/ProfileController.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/lib/Controller/CalendarController.php b/solid/lib/Controller/CalendarController.php index 7cd59b7f..0a4dff47 100644 --- a/solid/lib/Controller/CalendarController.php +++ b/solid/lib/Controller/CalendarController.php @@ -127,7 +127,7 @@ public function handleRequest($userId, $path) { $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); $notifications = new SolidNotifications(); - $this->resourceServer->setNotifications($notification); + $this->resourceServer->setNotifications($notifications); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ContactsController.php b/solid/lib/Controller/ContactsController.php index 1f4359b4..63c0852b 100644 --- a/solid/lib/Controller/ContactsController.php +++ b/solid/lib/Controller/ContactsController.php @@ -127,7 +127,7 @@ public function handleRequest($userId, $path) { $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); $notifications = new SolidNotifications(); - $this->resourceServer->setNotifications($notification); + $this->resourceServer->setNotifications($notifications); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ProfileController.php b/solid/lib/Controller/ProfileController.php index caec62ef..eb27a0ec 100644 --- a/solid/lib/Controller/ProfileController.php +++ b/solid/lib/Controller/ProfileController.php @@ -144,7 +144,7 @@ public function handleRequest($userId, $path) { $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); $notifications = new SolidNotifications(); - $this->resourceServer->setNotifications($notification); + $this->resourceServer->setNotifications($notifications); if ($request->getHeaderLine("DPop")) { try { From 818c93bea7ff067d36d4b04e368cb328baa44698 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:39:46 +0200 Subject: [PATCH 10/91] update TODO --- solid/TODO.Notifications | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications index 9af93c0b..06c47ad2 100644 --- a/solid/TODO.Notifications +++ b/solid/TODO.Notifications @@ -1,15 +1,19 @@ +TODO: - [ ] advertise the notifications channel in well-known - [ ] advertise the notifications channel in HTTP headers - [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud -- [ ] add notifications controller -- [ ] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry +- [ ] add notifications controller - [ ] handle register requests - this must validate that the requestor has read access to the resource; - [ ] handle unregister requests - only the webid that subscribed should be able to unsubscribe - [ ] implement function to get subscription in SolidWebHook + +Backlog / later: - [ ] add actor to notifications - [ ] add UUID to notifications - - [ ] Add support for the rate limit feature. - [ ] create a solid-notifications-lastsent database table - columns are subscription_id and lastsent; - [ ] how can we stop sending notifications when read access was revoked? + +Done: +- [v] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry From ad25122984952069eac5b78f0078bc82b6d4f678 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:41:43 +0200 Subject: [PATCH 11/91] fix variable names (url -> webhookUrl) to be more clear --- solid/lib/Notifications/SolidWebHook.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php index d379bb5f..c67778b9 100644 --- a/solid/lib/Notifications/SolidWebHook.php +++ b/solid/lib/Notifications/SolidWebHook.php @@ -5,14 +5,14 @@ class SolidWebhook implements SolidNotificationsInterface { public function send($path, $type) { $subscribedUrls = $this->getSubscribedUrls($path, $type); - foreach ($subscribedUrls as $url) { - $this->postUpdate($url, $path, $type); + foreach ($subscribedUrls as $webhookUrl) { + $this->postUpdate($webhookUrl, $path, $type); } } private function getSubscribedUrls($path, $type) { return []; // FIXME: Read this from the subscriptions } - private function postUpdate($url, $path, $type) { + private function postUpdate($webhookUrl, $path, $type) { try { $postData = $this->createUpdatePayload($path, $type); $opts = array('http' => @@ -23,7 +23,7 @@ private function postUpdate($url, $path, $type) { ) ); $context = stream_context_create($opts); - $result = file_get_contents($webhook, false, $context); + $result = file_get_contents($webhookUrl, false, $context); } catch (\Exception $exception) { throw new Exception('Could not write to webhook server', 502, $exception); } From 8eed3b67399a4f040acdf629aea2138417a39806 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 13:40:41 +0200 Subject: [PATCH 12/91] rename to change case --- .../Notifications/{SolidWebHook.php => SolidWebHook.php.moved} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename solid/lib/Notifications/{SolidWebHook.php => SolidWebHook.php.moved} (100%) diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php.moved similarity index 100% rename from solid/lib/Notifications/SolidWebHook.php rename to solid/lib/Notifications/SolidWebHook.php.moved From d886236dc9ee3c0c2087253f10a5d42151b09bf7 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 13:41:01 +0200 Subject: [PATCH 13/91] rename to change case --- solid/lib/Notifications/SolidWebhook.php | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 solid/lib/Notifications/SolidWebhook.php diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php new file mode 100644 index 00000000..c67778b9 --- /dev/null +++ b/solid/lib/Notifications/SolidWebhook.php @@ -0,0 +1,57 @@ +getSubscribedUrls($path, $type); + foreach ($subscribedUrls as $webhookUrl) { + $this->postUpdate($webhookUrl, $path, $type); + } + } + private function getSubscribedUrls($path, $type) { + return []; // FIXME: Read this from the subscriptions + } + private function postUpdate($webhookUrl, $path, $type) { + try { + $postData = $this->createUpdatePayload($path, $type); + $opts = array('http' => + array( + 'method' => 'POST', + 'header' => 'Content-Type: application/ld+json', + 'content' => $postData + ) + ); + $context = stream_context_create($opts); + $result = file_get_contents($webhookUrl, false, $context); + } catch (\Exception $exception) { + throw new Exception('Could not write to webhook server', 502, $exception); + } + } + private function createUpdatePayload($path, $type) { + //$updateId = "urn:uuid:"; + //$actor = ""; + $object = [ + "id" => $path, + "type" => [ + "http://www.w3.org/ns/ldp#Resource" + ] + ]; + $state = "1234-5678-90ab-cdef-12345678"; + $published = date(DATE_ISO8601); + $payload = [ + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://www.w3.org/ns/solid/notification/v1" + ], + // "id":$updateId, + // "actor" : [$actor], + "type" => [$type], + "object" => $object, + // "state" : $state + "published" => $published + ]; + + return json_encode($payload); + } + } From b4d9bb23238e76c9a419f0935a28eb3fc75f12a2 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 13:41:18 +0200 Subject: [PATCH 14/91] removed --- .../lib/Notifications/SolidWebHook.php.moved | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 solid/lib/Notifications/SolidWebHook.php.moved diff --git a/solid/lib/Notifications/SolidWebHook.php.moved b/solid/lib/Notifications/SolidWebHook.php.moved deleted file mode 100644 index c67778b9..00000000 --- a/solid/lib/Notifications/SolidWebHook.php.moved +++ /dev/null @@ -1,57 +0,0 @@ -getSubscribedUrls($path, $type); - foreach ($subscribedUrls as $webhookUrl) { - $this->postUpdate($webhookUrl, $path, $type); - } - } - private function getSubscribedUrls($path, $type) { - return []; // FIXME: Read this from the subscriptions - } - private function postUpdate($webhookUrl, $path, $type) { - try { - $postData = $this->createUpdatePayload($path, $type); - $opts = array('http' => - array( - 'method' => 'POST', - 'header' => 'Content-Type: application/ld+json', - 'content' => $postData - ) - ); - $context = stream_context_create($opts); - $result = file_get_contents($webhookUrl, false, $context); - } catch (\Exception $exception) { - throw new Exception('Could not write to webhook server', 502, $exception); - } - } - private function createUpdatePayload($path, $type) { - //$updateId = "urn:uuid:"; - //$actor = ""; - $object = [ - "id" => $path, - "type" => [ - "http://www.w3.org/ns/ldp#Resource" - ] - ]; - $state = "1234-5678-90ab-cdef-12345678"; - $published = date(DATE_ISO8601); - $payload = [ - "@context" => [ - "https://www.w3.org/ns/activitystreams", - "https://www.w3.org/ns/solid/notification/v1" - ], - // "id":$updateId, - // "actor" : [$actor], - "type" => [$type], - "object" => $object, - // "state" : $state - "published" => $published - ]; - - return json_encode($payload); - } - } From a03717cc64d4ac11b1f62e41aa3fdb6cb27132fc Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:49:20 +0200 Subject: [PATCH 15/91] Revert "use dev branch" This reverts commit 1559a3d8bea70886464b47318c62b99396dc02d6. --- solid/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/composer.json b/solid/composer.json index 42617404..3cef351f 100644 --- a/solid/composer.json +++ b/solid/composer.json @@ -30,7 +30,7 @@ "pdsinterop/flysystem-nextcloud":"^0.2", "pdsinterop/flysystem-rdf": "^0.5", "pdsinterop/solid-auth": "^0.7", - "pdsinterop/solid-crud": "dev-feature/notificationsInterface", + "pdsinterop/solid-crud": "^0.6", "psr/log" : "^1.1" }, "require-dev": { From 7451a6e952df7717809990ec07a9d91b1fc23957 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:49:29 +0200 Subject: [PATCH 16/91] Revert "update composer.lock" This reverts commit 625cdb59b811f80b88b20d4d5a07b0811409017f. --- solid/composer.lock | 150 +++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 77 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index 4c9ccf3c..876aaff9 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", + "content-hash": "5d63fb5c291e8f16e3e0b5cd42de117c", "packages": [ { "name": "arc/base", @@ -433,24 +433,25 @@ }, { "name": "laminas/laminas-diactoros", - "version": "2.17.0", + "version": "2.14.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5" + "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", - "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6cb35f61913f06b2c91075db00f67cfd78869e28", + "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28", "shasum": "" }, "require": { - "php": "^7.4 || ~8.0.0 || ~8.1.0", + "php": "^7.3 || ~8.0.0 || ~8.1.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0" }, "conflict": { + "phpspec/prophecy": "<1.9.0", "zendframework/zend-diactoros": "*" }, "provide": { @@ -463,9 +464,10 @@ "ext-gd": "*", "ext-libxml": "*", "http-interop/http-factory-tests": "^0.9.0", - "laminas/laminas-coding-standard": "^2.4.0", + "laminas/laminas-coding-standard": "~2.3.0", "php-http/psr7-integration-tests": "^1.1.1", - "phpunit/phpunit": "^9.5.23", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", "psalm/plugin-phpunit": "^0.17.0", "vimeo/psalm": "^4.24.0" }, @@ -526,7 +528,7 @@ "type": "community_bridge" } ], - "time": "2022-08-30T17:01:46+00:00" + "time": "2022-07-28T12:23:48+00:00" }, { "name": "lcobucci/clock", @@ -1008,38 +1010,37 @@ }, { "name": "league/uri", - "version": "6.8.0", + "version": "6.7.1", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39" + "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/a700b4656e4c54371b799ac61e300ab25a2d1d39", - "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", + "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", "shasum": "" }, "require": { "ext-json": "*", "league/uri-interfaces": "^2.3", - "php": "^8.1", - "psr/http-message": "^1.0.1" + "php": "^7.4 || ^8.0", + "psr/http-message": "^1.0" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^v3.9.5", - "nyholm/psr7": "^1.5.1", - "php-http/psr7-integration-tests": "^1.1.1", - "phpbench/phpbench": "^1.2.6", - "phpstan/phpstan": "^1.8.5", + "friendsofphp/php-cs-fixer": "^v3.3.2", + "nyholm/psr7": "^1.5", + "php-http/psr7-integration-tests": "^1.1", + "phpstan/phpstan": "^1.2.0", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.1.1", - "phpstan/phpstan-strict-rules": "^1.4.3", - "phpunit/phpunit": "^9.5.24", - "psr/http-factory": "^1.0.1" + "phpstan/phpstan-phpunit": "^1.0.0", + "phpstan/phpstan-strict-rules": "^1.1.0", + "phpunit/phpunit": "^9.5.10", + "psr/http-factory": "^1.0" }, "suggest": { "ext-fileinfo": "Needed to create Data URI from a filepath", @@ -1096,7 +1097,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.8.0" + "source": "https://github.com/thephpleague/uri/tree/6.7.1" }, "funding": [ { @@ -1104,7 +1105,7 @@ "type": "github" } ], - "time": "2022-09-13T19:58:47+00:00" + "time": "2022-06-29T09:48:18+00:00" }, { "name": "league/uri-interfaces", @@ -1536,16 +1537,16 @@ }, { "name": "pdsinterop/solid-crud", - "version": "dev-feature/notificationsInterface", + "version": "v0.6.0", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838" + "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/d68164b50b6b575a7f634aa87374fba3ef84a838", - "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", + "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", "shasum": "" }, "require": { @@ -1560,9 +1561,6 @@ "psr/http-message": "^1.0", "textalk/websocket": "^1.5" }, - "require-dev": { - "phpunit/phpunit": "^9" - }, "type": "library", "autoload": { "psr-4": { @@ -1576,9 +1574,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.6.0" }, - "time": "2022-09-16T13:37:05+00:00" + "time": "2022-08-24T08:13:54+00:00" }, { "name": "pietercolpaert/hardf", @@ -2265,16 +2263,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -2315,9 +2313,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "phar-io/manifest", @@ -2432,16 +2430,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "9.2.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", "shasum": "" }, "require": { @@ -2497,7 +2495,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" }, "funding": [ { @@ -2505,7 +2503,7 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2022-08-20T05:26:47+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2750,16 +2748,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.24", + "version": "9.5.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" + "reference": "888556852e7e9bbeeedb9656afe46118765ade34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", + "reference": "888556852e7e9bbeeedb9656afe46118765ade34", "shasum": "" }, "require": { @@ -2788,7 +2786,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.1", + "sebastian/type": "^3.0", "sebastian/version": "^3.0.2" }, "suggest": { @@ -2832,7 +2830,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" }, "funding": [ { @@ -2844,7 +2842,7 @@ "type": "github" } ], - "time": "2022-08-30T07:42:16+00:00" + "time": "2022-08-22T14:01:36+00:00" }, { "name": "sebastian/cli-parser", @@ -3015,16 +3013,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { @@ -3077,7 +3075,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" }, "funding": [ { @@ -3085,7 +3083,7 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2020-10-26T15:49:45+00:00" }, { "name": "sebastian/complexity", @@ -3275,16 +3273,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.5", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -3340,7 +3338,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { @@ -3348,7 +3346,7 @@ "type": "github" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", @@ -3703,16 +3701,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", "shasum": "" }, "require": { @@ -3724,7 +3722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -3747,7 +3745,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" }, "funding": [ { @@ -3755,7 +3753,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", @@ -3863,9 +3861,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "pdsinterop/solid-crud": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3874,5 +3870,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From e7add1685b5e3a8ebfb77cfececbb3877fa4f65d Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:54:24 +0200 Subject: [PATCH 17/91] rename table --- solid/composer.json | 2 +- solid/composer.lock | 23 +++++++++++-------- .../Version000000Date20220919084800.php | 11 ++++----- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/solid/composer.json b/solid/composer.json index 3cef351f..42617404 100644 --- a/solid/composer.json +++ b/solid/composer.json @@ -30,7 +30,7 @@ "pdsinterop/flysystem-nextcloud":"^0.2", "pdsinterop/flysystem-rdf": "^0.5", "pdsinterop/solid-auth": "^0.7", - "pdsinterop/solid-crud": "^0.6", + "pdsinterop/solid-crud": "dev-feature/notificationsInterface", "psr/log" : "^1.1" }, "require-dev": { diff --git a/solid/composer.lock b/solid/composer.lock index 876aaff9..90b84237 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5d63fb5c291e8f16e3e0b5cd42de117c", + "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", "packages": [ { "name": "arc/base", @@ -1537,16 +1537,16 @@ }, { "name": "pdsinterop/solid-crud", - "version": "v0.6.0", + "version": "dev-feature/notificationsInterface", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474" + "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", + "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", "shasum": "" }, "require": { @@ -1561,6 +1561,9 @@ "psr/http-message": "^1.0", "textalk/websocket": "^1.5" }, + "require-dev": { + "phpunit/phpunit": "^9" + }, "type": "library", "autoload": { "psr-4": { @@ -1574,9 +1577,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.6.0" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" }, - "time": "2022-08-24T08:13:54+00:00" + "time": "2022-09-19T06:45:41+00:00" }, { "name": "pietercolpaert/hardf", @@ -3861,7 +3864,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "pdsinterop/solid-crud": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3870,5 +3875,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.1.0" } diff --git a/solid/lib/Migration/Version000000Date20220919084800.php b/solid/lib/Migration/Version000000Date20220919084800.php index 82d71197..3db0c258 100644 --- a/solid/lib/Migration/Version000000Date20220919084800.php +++ b/solid/lib/Migration/Version000000Date20220919084800.php @@ -10,7 +10,6 @@ use OCP\Migration\IOutput; class Version000000Date20220919084800 extends SimpleMigrationStep { - /** * @param IOutput $output * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` @@ -21,14 +20,14 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); - if (!$schema->hasTable('solid_notifications_webhooks')) { - $table = $schema->createTable('solid_notifications_webhooks'); + if (!$schema->hasTable('solid_webhooks')) { + $table = $schema->createTable('solid_webhooks'); // id, webid, path, url, expiry $table->addColumn('id', 'integer', [ 'autoincrement' => true, 'notnull' => true, ]); - $table->addColumn('webid', 'string', [ + $table->addColumn('web_id', 'string', [ 'notnull' => true, 'length' => 2048 ]); @@ -46,8 +45,8 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt ]); $table->setPrimaryKey(['id']); - $table->addIndex(['webid'], 'solid_notifications_webhooks_webid_index'); - $table->addIndex(['path'], 'solid_notifications_webhooks_path_index'); + $table->addIndex(['web_id'], 'solid_webhooks_web_id_index'); + $table->addIndex(['path'], 'solid_webhooks_path_index'); } return $schema; } From 246d3f86be7c13ee79584c363b9d3aefc022cbbe Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:56:27 +0200 Subject: [PATCH 18/91] add entity and Db mapper --- solid/lib/Db/SolidWebhook.php | 25 +++++++++++++ solid/lib/Db/SolidWebhookMapper.php | 58 +++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 solid/lib/Db/SolidWebhook.php create mode 100644 solid/lib/Db/SolidWebhookMapper.php diff --git a/solid/lib/Db/SolidWebhook.php b/solid/lib/Db/SolidWebhook.php new file mode 100644 index 00000000..330d027a --- /dev/null +++ b/solid/lib/Db/SolidWebhook.php @@ -0,0 +1,25 @@ + $this->id, + 'webId' => $this->webId, + 'path' => $this->path, + 'url' => $this->url, + 'expiry' => $this->expiry + ]; + } +} diff --git a/solid/lib/Db/SolidWebhookMapper.php b/solid/lib/Db/SolidWebhookMapper.php new file mode 100644 index 00000000..fa35ec76 --- /dev/null +++ b/solid/lib/Db/SolidWebhookMapper.php @@ -0,0 +1,58 @@ +db->getQueryBuilder(); + $qb->select('*') + ->from('solid_webhooks') + ->where($qb->expr()->eq('web_id', $qb->createNamedParameter($webId))) + ->andWhere($qb->expr()->eq('path', $qb->createNamedParameter($path))); + return $this->findEntity($qb); + } + + /** + * @param string $webId + * @return array + */ + public function findAll(string $webId): array { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('solid_webhooks') + ->where($qb->expr()->eq('web_id', $qb->createNamedParameter($webId))); + return $this->findEntities($qb); + } + + /** + * @param string $path + * @return array + */ + public function findByPath(string $path): array { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('solid_webhooks') + ->where($qb->expr()->eq('path', $qb->createNamedParameter($path))); + return $this->findEntities($qb); + } +} From 5739d0d2c443ce1707b6c4420ad56283f3de8a50 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:56:58 +0200 Subject: [PATCH 19/91] add solidwebhook service --- solid/lib/Service/SolidWebhookNotFound.php | 6 ++ solid/lib/Service/SolidWebhookService.php | 65 ++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 solid/lib/Service/SolidWebhookNotFound.php create mode 100644 solid/lib/Service/SolidWebhookService.php diff --git a/solid/lib/Service/SolidWebhookNotFound.php b/solid/lib/Service/SolidWebhookNotFound.php new file mode 100644 index 00000000..7a06886f --- /dev/null +++ b/solid/lib/Service/SolidWebhookNotFound.php @@ -0,0 +1,6 @@ +mapper = $mapper; + } + + public function findAll(string $webId): array { + return $this->mapper->findAll($webId); + } + + public function findByPath(string $path): array { + return $this->mapper->findByPath($path); + } + + private function handleException(Exception $e): void { + if ($e instanceof DoesNotExistException || + $e instanceof MultipleObjectsReturnedException) { + throw new SolidWebhookNotFound($e->getMessage()); + } else { + throw $e; + } + } + + public function find($webId, $path) { + try { + return $this->mapper->find($webId, $path); + } catch (Exception $e) { + $this->handleException($e); + } + } + + public function create($webId, $path, $url, $expiry) { + $webhook = new SolidWebhook(); + $webhook->setWebId($webId); + $webhook->setPath($path); + $webHook->setUrl($url); + $webHook->setExpiry($expiry); + return $this->mapper->insert($note); + } + + public function delete($webId, $path) { + try { + $webhook = $this->mapper->find($webId, $path); + $this->mapper->delete($webhook); + return $webhook; + } catch (Exception $e) { + $this->handleException($e); + } + } +} From c48cd28633bdf25055f700e80162b0e8de443abb Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:57:35 +0200 Subject: [PATCH 20/91] add SolidWebhook controller --- .../lib/Controller/SolidWebhookController.php | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 solid/lib/Controller/SolidWebhookController.php diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php new file mode 100644 index 00000000..8e6cdae8 --- /dev/null +++ b/solid/lib/Controller/SolidWebhookController.php @@ -0,0 +1,188 @@ +config = new \OCA\Solid\ServerConfig($config, $urlGenerator, $userManager); + $this->rootFolder = $rootFolder; + $this->request = $request; + $this->urlGenerator = $urlGenerator; + $this->session = $session; + $this->webhookService = $webhookService; + + $this->DPop = new DPop(); + try { + $this->webId = $this->DPop->getWebId($request); + } catch(\Exception $e) { + $response = $this->resourceServer->getResponse()->withStatus(409, "Invalid token"); + return $this->respond($response); + } + } + + /** + * @PublicPage + * @NoAdminRequired + * @NoCSRFRequired + */ + public function listWebhooks(): DataResponse { + return new DataResponse($this->webhookService->findAll($this->webId)); + } + + /** + * @PublicPage + * @NoAdminRequired + * @NoCSRFRequired + */ + public function register(string $targetUrl, string $webhookUrl, string $expiry): DataResponse { + // FIXME: Validate WAC read access to the target URL for $this->webId + if ($this->checkReadAccess($targetUrl)) { + return new DataResponse($this->webhookService->create($this->webId, $targetUrl, $webhookUrl, $expiry)); + } + } + + /** + * @PublicPage + * @NoAdminRequired + * @NoCSRFRequired + */ + public function unregister(string $targetUrl): DataResponse { + return $this->handleNotFound(function () use ($targetUrl) { + return $this->webhookService->delete($this->webId, $targetUrl); + }); + } + + + private function getFileSystem() { + // Create the Nextcloud Adapter + $adapter = new \Pdsinterop\Flysystem\Adapter\Nextcloud($this->solidFolder); + $graph = new \EasyRdf\Graph(); + + // Create Formats objects + $formats = new \Pdsinterop\Rdf\Formats(); + + $serverUri = "https://" . $this->rawRequest->getServerParams()["SERVER_NAME"] . $this->rawRequest->getServerParams()["REQUEST_URI"]; // FIXME: doublecheck that this is the correct url; + + // Create the RDF Adapter + $rdfAdapter = new \Pdsinterop\Rdf\Flysystem\Adapter\Rdf( + $adapter, + $graph, + $formats, + $serverUri + ); + + $filesystem = new \League\Flysystem\Filesystem($rdfAdapter); + + $filesystem->addPlugin(new \Pdsinterop\Rdf\Flysystem\Plugin\AsMime($formats)); + + $plugin = new \Pdsinterop\Rdf\Flysystem\Plugin\ReadRdf($graph); + $filesystem->addPlugin($plugin); + + return $filesystem; + } + + private function getStorageUrl($userId) { + $storageUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.storage.handleHead", array("userId" => $userId, "path" => "foo"))); + $storageUrl = preg_replace('/foo$/', '', $storageUrl); + return $storageUrl; + } + private function getAppBaseUrl($userId) { + $appBaseUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.app.appLauncher")); + return $appBaseUrl; + } + private function initializeStorage($userId) { + $this->userFolder = $this->rootFolder->getUserFolder($userId); + $this->solidFolder = $this->userFolder->get("solid"); + $this->filesystem = $this->getFileSystem(); + } + + private function parseTargetUrl($targetUrl) { + // targetUrl = https://nextcloud.server/solid/@alice/storage/foo/bar + $appBaseUrl = $this->getAppBaseUrl(); // https://nextcloud.server/solid/ + $internalUrl = str_replace($appBaseUrl, '', $targetUrl); // @alice/storage/foo/bar + $pathicles = explode($internalUrl, "/"); + $userId = $pathicles[0]; // alice + + $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ + $storagePath = str_replace($storageUrl, '/', $targetUrl); // /foo/bar + return array("userId" => $userId, "path", $storagePath); + } + + private function createGetRequest($targetUrl) { + $serverParams = []; + $fileParams = []; + $method = "GET"; + $body = null; + $headers = []; + + return new \Laminas\Diactoros\ServerRequest( + $serverParams, + $fileParams, + $targetUrl, + $method, + $body, + $headers + ); + } + + private function checkReadAccess($targetUrl) { + // split out $targetUrl into $userId and $path https://nextcloud.server/solid/@alice/storage/foo/bar + // - userId in this case is the pod owner (not the one doing the request). (alice) + // - path is the path within the storage pod (/foo/bar) + $target = $this->parseTargetUrl($targetUrl); + $userId = $target["userId"]; + $path = $target["path"]; + + $this->initializeStorage($userId); + $this->WAC = new WAC($this->filesystem); + + $baseUrl = $this->getStorageUrl($userId); + $this->WAC->setBaseUrl($baseUrl); + + $serverParams = []; + $fileParams = []; + + $request = $this->createGetRequest($targetUrl); + if (!$this->WAC->isAllowed($request, $this->webId)) { // Deny if we don't have read grants on the URL; + return false; + } + return true; + } +} From 39563e21e0efa71a12798279938cf2a20647a9d0 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:00:09 +0200 Subject: [PATCH 21/91] add routes --- solid/appinfo/routes.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solid/appinfo/routes.php b/solid/appinfo/routes.php index 89011912..c000caf6 100644 --- a/solid/appinfo/routes.php +++ b/solid/appinfo/routes.php @@ -51,6 +51,10 @@ ['name' => 'contacts#handlePatch', 'url' => '/@{userId}/contacts{path}', 'verb' => 'PATCH', 'requirements' => array('path' => '.+')], ['name' => 'contacts#handleHead', 'url' => '/@{userId}/contacts{path}', 'verb' => 'HEAD', 'requirements' => array('path' => '.+')], + ['name' => 'solidwebhook#listWebhooks', 'url' => '/webhook/list', 'verb' => 'GET'], + ['name' => 'solidwebhook#register', 'url' => '/webhook/register', 'verb' => 'POST'], + ['name' => 'solidwebhook#unregister', 'url' => '/webhook/unregister', 'verb' => 'POST'], + ['name' => 'app#appLauncher', 'url' => '/', 'verb' => 'GET'], ] ]; From 9ee0aa1ff3a3a0222580e12118de0f9d44317b1b Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:02:53 +0200 Subject: [PATCH 22/91] whitespace - fix sniff --- solid/lib/Service/SolidWebhookService.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/solid/lib/Service/SolidWebhookService.php b/solid/lib/Service/SolidWebhookService.php index 2e93da1f..60263a86 100644 --- a/solid/lib/Service/SolidWebhookService.php +++ b/solid/lib/Service/SolidWebhookService.php @@ -11,7 +11,6 @@ use OCA\Solid\Db\SolidWebhookMapper; class SolidWebhookService { - /** @var SolidWebhookMapper */ private $mapper; @@ -28,8 +27,10 @@ public function findByPath(string $path): array { } private function handleException(Exception $e): void { - if ($e instanceof DoesNotExistException || - $e instanceof MultipleObjectsReturnedException) { + if ( + $e instanceof DoesNotExistException || + $e instanceof MultipleObjectsReturnedException + ) { throw new SolidWebhookNotFound($e->getMessage()); } else { throw $e; From dbe11242880a22c5033d66b5c98b0ae5ffdfa05c Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:22:21 +0200 Subject: [PATCH 23/91] update namespace --- solid/lib/Notifications/SolidNotifications.php | 2 +- solid/lib/Notifications/SolidPubSub.php | 2 +- solid/lib/Notifications/SolidWebhook.php | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/solid/lib/Notifications/SolidNotifications.php b/solid/lib/Notifications/SolidNotifications.php index dac12069..89ee428a 100644 --- a/solid/lib/Notifications/SolidNotifications.php +++ b/solid/lib/Notifications/SolidNotifications.php @@ -3,7 +3,7 @@ use OCA\Solid\Notifications\SolidPubSub; use OCA\Solid\Notifications\SolidWebhook; - use Pdsinterop\Solid\SolidNotificationsInterface; + use Pdsinterop\Solid\SolidNotifications\SolidNotificationsInterface; class SolidNotifications implements SolidNotificationsInterface { diff --git a/solid/lib/Notifications/SolidPubSub.php b/solid/lib/Notifications/SolidPubSub.php index 07291cf5..e0acaf4c 100644 --- a/solid/lib/Notifications/SolidPubSub.php +++ b/solid/lib/Notifications/SolidPubSub.php @@ -2,7 +2,7 @@ namespace OCA\Solid\Notifications; use WebSocket\Client; - use Pdsinterop\Solid\SolidNotificationsInterface; + use Pdsinterop\Solid\SolidNotifications\SolidNotificationsInterface; class SolidPubSub implements SolidNotificationsInterface { diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index c67778b9..b5483d78 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -1,6 +1,8 @@ Date: Mon, 19 Sep 2022 16:44:49 +0200 Subject: [PATCH 24/91] update solid-crud --- solid/composer.lock | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index 90b84237..c0f600a8 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -1541,12 +1541,12 @@ "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2" + "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", - "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", + "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", "shasum": "" }, "require": { @@ -1567,7 +1567,8 @@ "type": "library", "autoload": { "psr-4": { - "Pdsinterop\\Solid\\Resources\\": "src/" + "Pdsinterop\\Solid\\Resources\\": "src/", + "Pdsinterop\\Solid\\SolidNotifications\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1579,7 +1580,7 @@ "issues": "https://github.com/pdsinterop/php-solid-crud/issues", "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" }, - "time": "2022-09-19T06:45:41+00:00" + "time": "2022-09-19T14:41:18+00:00" }, { "name": "pietercolpaert/hardf", From f3b469bebbcbc83d7188bab0ab25275cc23fcef2 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:58:50 +0200 Subject: [PATCH 25/91] fix case --- solid/appinfo/routes.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/appinfo/routes.php b/solid/appinfo/routes.php index c000caf6..c106a0e4 100644 --- a/solid/appinfo/routes.php +++ b/solid/appinfo/routes.php @@ -51,9 +51,9 @@ ['name' => 'contacts#handlePatch', 'url' => '/@{userId}/contacts{path}', 'verb' => 'PATCH', 'requirements' => array('path' => '.+')], ['name' => 'contacts#handleHead', 'url' => '/@{userId}/contacts{path}', 'verb' => 'HEAD', 'requirements' => array('path' => '.+')], - ['name' => 'solidwebhook#listWebhooks', 'url' => '/webhook/list', 'verb' => 'GET'], - ['name' => 'solidwebhook#register', 'url' => '/webhook/register', 'verb' => 'POST'], - ['name' => 'solidwebhook#unregister', 'url' => '/webhook/unregister', 'verb' => 'POST'], + ['name' => 'solidWebhook#listWebhooks', 'url' => '/webhook/list', 'verb' => 'GET'], + ['name' => 'solidWebhook#register', 'url' => '/webhook/register', 'verb' => 'POST'], + ['name' => 'solidWebhook#unregister', 'url' => '/webhook/unregister', 'verb' => 'POST'], ['name' => 'app#appLauncher', 'url' => '/', 'verb' => 'GET'], ] From be8c7836c1c432feb0bf0d54c5ff028d3767bd96 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 17:00:52 +0200 Subject: [PATCH 26/91] use raw request instead of nextcloud request object --- solid/lib/Controller/SolidWebhookController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 8e6cdae8..7f0603da 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -50,7 +50,8 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request $this->DPop = new DPop(); try { - $this->webId = $this->DPop->getWebId($request); + $rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); + $this->webId = $this->DPop->getWebId($rawRequest); } catch(\Exception $e) { $response = $this->resourceServer->getResponse()->withStatus(409, "Invalid token"); return $this->respond($response); From f6679c102338aa2659d6ab9aee7c5056176439d5 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 09:39:51 +0200 Subject: [PATCH 27/91] bugfixing drycoded controller --- solid/lib/Controller/SolidWebhookController.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 7f0603da..122b29f2 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -53,8 +53,7 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request $rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); $this->webId = $this->DPop->getWebId($rawRequest); } catch(\Exception $e) { - $response = $this->resourceServer->getResponse()->withStatus(409, "Invalid token"); - return $this->respond($response); + return new PlainResponse("Invalid token", 409); } } @@ -124,7 +123,7 @@ private function getStorageUrl($userId) { $storageUrl = preg_replace('/foo$/', '', $storageUrl); return $storageUrl; } - private function getAppBaseUrl($userId) { + private function getAppBaseUrl() { $appBaseUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.app.appLauncher")); return $appBaseUrl; } @@ -138,12 +137,15 @@ private function parseTargetUrl($targetUrl) { // targetUrl = https://nextcloud.server/solid/@alice/storage/foo/bar $appBaseUrl = $this->getAppBaseUrl(); // https://nextcloud.server/solid/ $internalUrl = str_replace($appBaseUrl, '', $targetUrl); // @alice/storage/foo/bar - $pathicles = explode($internalUrl, "/"); + $pathicles = explode("/", $internalUrl); $userId = $pathicles[0]; // alice $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ $storagePath = str_replace($storageUrl, '/', $targetUrl); // /foo/bar - return array("userId" => $userId, "path", $storagePath); + return array( + "userId" => $userId, + "path" => $storagePath + ); } private function createGetRequest($targetUrl) { From 222088648896a70de3276aa173ca6f98f58c69da Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 09:45:41 +0200 Subject: [PATCH 28/91] more bugfixes for drycoded --- solid/lib/Controller/SolidWebhookController.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 122b29f2..12134781 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -50,8 +50,8 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request $this->DPop = new DPop(); try { - $rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); - $this->webId = $this->DPop->getWebId($rawRequest); + $this->rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); + $this->webId = $this->DPop->getWebId($this->rawRequest); } catch(\Exception $e) { return new PlainResponse("Invalid token", 409); } @@ -138,9 +138,9 @@ private function parseTargetUrl($targetUrl) { $appBaseUrl = $this->getAppBaseUrl(); // https://nextcloud.server/solid/ $internalUrl = str_replace($appBaseUrl, '', $targetUrl); // @alice/storage/foo/bar $pathicles = explode("/", $internalUrl); - $userId = $pathicles[0]; // alice - - $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ + $userId = $pathicles[0]; // @alice + $userId = preg_replace("/^@/", "", $userId); // alice + $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ $storagePath = str_replace($storageUrl, '/', $targetUrl); // /foo/bar return array( "userId" => $userId, From dcc335ddf7abda0296533417986f502fd6075b3b Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:32:04 +0200 Subject: [PATCH 29/91] use memory to provide a stream --- solid/lib/Controller/SolidWebhookController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 12134781..d0971014 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -152,7 +152,7 @@ private function createGetRequest($targetUrl) { $serverParams = []; $fileParams = []; $method = "GET"; - $body = null; + $body = 'php://memory'; $headers = []; return new \Laminas\Diactoros\ServerRequest( From 5e986758bbc456ec4d93f105b92eb7011a8d38a1 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:32:27 +0200 Subject: [PATCH 30/91] make $id public --- solid/lib/Db/SolidWebhook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/lib/Db/SolidWebhook.php b/solid/lib/Db/SolidWebhook.php index 330d027a..8fcab4ac 100644 --- a/solid/lib/Db/SolidWebhook.php +++ b/solid/lib/Db/SolidWebhook.php @@ -7,7 +7,7 @@ use OCP\AppFramework\Db\Entity; class SolidWebhook extends Entity implements JsonSerializable { - protected $id; + public $id; protected $path; protected $webId; protected $url; From 9f047250c8c16a40ac10a418adbc9274c16b2fe1 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:32:50 +0200 Subject: [PATCH 31/91] typofixes --- solid/lib/Service/SolidWebhookService.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/lib/Service/SolidWebhookService.php b/solid/lib/Service/SolidWebhookService.php index 60263a86..b8c9dc61 100644 --- a/solid/lib/Service/SolidWebhookService.php +++ b/solid/lib/Service/SolidWebhookService.php @@ -49,9 +49,9 @@ public function create($webId, $path, $url, $expiry) { $webhook = new SolidWebhook(); $webhook->setWebId($webId); $webhook->setPath($path); - $webHook->setUrl($url); - $webHook->setExpiry($expiry); - return $this->mapper->insert($note); + $webhook->setUrl($url); + $webhook->setExpiry($expiry); + return $this->mapper->insert($webhook); } public function delete($webId, $path) { From 9f5a0a7928d9669b0551d13c81bacb80934296b4 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:55:49 +0200 Subject: [PATCH 32/91] add error handler --- solid/lib/Controller/SolidWebhookController.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index d0971014..36ca4cfe 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -2,6 +2,7 @@ namespace OCA\Solid\Controller; +use Closure; use OCA\Solid\AppInfo\Application; use OCA\Solid\Service\SolidWebhookService; use OCA\Solid\ServerConfig; @@ -52,6 +53,7 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request try { $this->rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); $this->webId = $this->DPop->getWebId($this->rawRequest); + // FIXME: Should we handle webhooks for 'public'? } catch(\Exception $e) { return new PlainResponse("Invalid token", 409); } @@ -188,4 +190,13 @@ private function checkReadAccess($targetUrl) { } return true; } + + private function handleNotFound(Closure $callback): DataResponse { + try { + return new DataResponse($callback()); + } catch (SolidWebhookNotFound $e) { + $message = ['message' => $e->getMessage()]; + return new DataResponse($message, Http::STATUS_NOT_FOUND); + } + } } From 211bb9968186b3e68567341c69130dc629fd58e8 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:56:26 +0200 Subject: [PATCH 33/91] add code to fetch webhooks --- solid/lib/Notifications/SolidWebhook.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index b5483d78..e07d13e4 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -5,14 +5,23 @@ class SolidWebhook implements SolidNotificationsInterface { + public function __construct(\OCA\Solid\Service\SolidWebhookService $webhookService) { + $this->webhookService = $webhookService; + } + public function send($path, $type) { - $subscribedUrls = $this->getSubscribedUrls($path, $type); - foreach ($subscribedUrls as $webhookUrl) { - $this->postUpdate($webhookUrl, $path, $type); + $webhooks = $this->getWebhooks($path); + foreach ($webhooks as $webhook) { + try { + $this->postUpdate($webhook['url'], $path, $type); + } catch(\Exception $e) { + // FIXME: add retry code here? + } } } - private function getSubscribedUrls($path, $type) { - return []; // FIXME: Read this from the subscriptions + private function getWebhooks($path, $type) { + $urls = $this->webhookService->findByPath($path); + return $urls; } private function postUpdate($webhookUrl, $path, $type) { try { From d5c21c155246d30e72e04560dedf83bc9d5e459d Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:27:22 +0200 Subject: [PATCH 34/91] Setting up notification channels. --- solid/lib/Controller/CalendarController.php | 7 ++- solid/lib/Controller/ContactsController.php | 7 ++- solid/lib/Controller/ProfileController.php | 7 ++- solid/lib/Controller/StorageController.php | 6 +- .../lib/Notifications/SolidNotifications.php | 24 ++++++++ solid/lib/Notifications/SolidPubSub.php | 29 ++++++++++ solid/lib/Notifications/SolidWebHook.php | 56 +++++++++++++++++++ 7 files changed, 125 insertions(+), 11 deletions(-) create mode 100644 solid/lib/Notifications/SolidNotifications.php create mode 100644 solid/lib/Notifications/SolidPubSub.php create mode 100644 solid/lib/Notifications/SolidWebHook.php diff --git a/solid/lib/Controller/CalendarController.php b/solid/lib/Controller/CalendarController.php index 3a4c4054..7cd59b7f 100644 --- a/solid/lib/Controller/CalendarController.php +++ b/solid/lib/Controller/CalendarController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -118,15 +119,15 @@ public function handleRequest($userId, $path) { $this->filesystem = $this->getFileSystem($userId); $this->resourceServer = new ResourceServer($this->filesystem, $this->response); - $this->WAC = new WAC($this->filesystem); + $this->WAC = new WAC($this->filesystem); $this->DPop = new DPop(); $request = $this->rawRequest; $baseUrl = $this->getCalendarUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notification); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ContactsController.php b/solid/lib/Controller/ContactsController.php index cb95cf5b..1f4359b4 100644 --- a/solid/lib/Controller/ContactsController.php +++ b/solid/lib/Controller/ContactsController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -118,15 +119,15 @@ public function handleRequest($userId, $path) { $this->filesystem = $this->getFileSystem($userId); $this->resourceServer = new ResourceServer($this->filesystem, $this->response); - $this->WAC = new WAC($this->filesystem); + $this->WAC = new WAC($this->filesystem); $this->DPop = new DPop(); $request = $this->rawRequest; $baseUrl = $this->getContactsUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notification); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ProfileController.php b/solid/lib/Controller/ProfileController.php index 7d64f6f9..caec62ef 100644 --- a/solid/lib/Controller/ProfileController.php +++ b/solid/lib/Controller/ProfileController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -135,15 +136,15 @@ public function handleRequest($userId, $path) { $this->filesystem = $this->getFileSystem($userId); $this->resourceServer = new ResourceServer($this->filesystem, $this->response); - $this->WAC = new WAC($this->filesystem); + $this->WAC = new WAC($this->filesystem); $this->DPop = new DPop(); $request = $this->rawRequest; $baseUrl = $this->getProfileUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notification); if ($request->getHeaderLine("DPop")) { try { diff --git a/solid/lib/Controller/StorageController.php b/solid/lib/Controller/StorageController.php index 3f7fd16d..9cb5b234 100644 --- a/solid/lib/Controller/StorageController.php +++ b/solid/lib/Controller/StorageController.php @@ -3,6 +3,7 @@ use OCA\Solid\ServerConfig; use OCA\Solid\PlainResponse; +use OCA\Solid\Notifications\SolidNotifications; use OCP\IRequest; use OCP\IUserManager; @@ -287,8 +288,9 @@ public function handleRequest($userId, $path) { $baseUrl = $this->getStorageUrl($userId); $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); - $pubsub = getenv('PUBSUB_URL') ?: ("http://pubsub:8080/"); - $this->resourceServer->setPubSubUrl($pubsub); + + $notifications = new SolidNotifications(); + $this->resourceServer->setNotifications($notifications); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Notifications/SolidNotifications.php b/solid/lib/Notifications/SolidNotifications.php new file mode 100644 index 00000000..9fb640e8 --- /dev/null +++ b/solid/lib/Notifications/SolidNotifications.php @@ -0,0 +1,24 @@ +notifications = [ + new SolidWebhook(), + new SolidPubSub($pubsub) + ]; + } + + public function send($path, $type) { + foreach ($this->notifications as $notification) { + $notification->send($path, $type); + } + } + } \ No newline at end of file diff --git a/solid/lib/Notifications/SolidPubSub.php b/solid/lib/Notifications/SolidPubSub.php new file mode 100644 index 00000000..081e6f81 --- /dev/null +++ b/solid/lib/Notifications/SolidPubSub.php @@ -0,0 +1,29 @@ +pubsub = $pubsubUrl; + } + + public function send($path, $type) { + $pubsub = str_replace(["https://", "http://"], "ws://", $this->pubsub); + + $client = new Client($pubsub, array( + 'headers' => array( + 'Sec-WebSocket-Protocol' => 'solid-0.1' + ) + )); + + try { + $client->send("pub $path\n"); + } catch (\WebSocket\Exception $exception) { + throw new Exception('Could not write to pubsub server', 502, $exception); + } + } + } \ No newline at end of file diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php new file mode 100644 index 00000000..79a82ef5 --- /dev/null +++ b/solid/lib/Notifications/SolidWebHook.php @@ -0,0 +1,56 @@ +getSubscribedUrls($path, $type); + foreach ($subscribedUrls as $url) { + $this->postUpdate($url, $path, $type); + } + } + private function getSubscribedUrls($path, $type) { + } + private function postUpdate($url, $path, $type) { + try { + $postData = $this->createUpdatePayload($path, $type); + $opts = array('http' => + array( + 'method' => 'POST', + 'header' => 'Content-Type: application/ld+json', + 'content' => $postData + ) + ); + $context = stream_context_create($opts); + $result = file_get_contents($webhook, false, $context); + } catch (\Exception $exception) { + throw new Exception('Could not write to webhook server', 502, $exception); + } + } + private function createUpdatePayload($path, $type) { + //$updateId = "urn:uuid:"; + //$actor = ""; + $object = [ + "id" => $path, + "type" => [ + "http://www.w3.org/ns/ldp#Resource" + ] + ]; + $state = "1234-5678-90ab-cdef-12345678"; + $published = date(DATE_ISO8601); + $payload = [ + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://www.w3.org/ns/solid/notification/v1" + ], + // "id":$updateId, + // "actor" : [$actor], + "type" => [$type], + "object" => $object, + // "state" : $state + "published" => $published + ]; + + return json_encode($payload); + } + } \ No newline at end of file From dfd8b4f8530619d3495dbfd06d95b5fe9b9ea4ef Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:28:49 +0200 Subject: [PATCH 35/91] fix return type --- solid/lib/Notifications/SolidWebHook.php | 1 + 1 file changed, 1 insertion(+) diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php index 79a82ef5..225a8b85 100644 --- a/solid/lib/Notifications/SolidWebHook.php +++ b/solid/lib/Notifications/SolidWebHook.php @@ -10,6 +10,7 @@ public function send($path, $type) { } } private function getSubscribedUrls($path, $type) { + return []; // FIXME: Read this from the subscriptions } private function postUpdate($url, $path, $type) { try { From 6f65809b0434b30bce0be78bfa7e7e86fa0c1051 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:36:10 +0200 Subject: [PATCH 36/91] add TODO list for what needs to be done for this feature to be complete --- solid/TODO.Notifications | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 solid/TODO.Notifications diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications new file mode 100644 index 00000000..eaaf6669 --- /dev/null +++ b/solid/TODO.Notifications @@ -0,0 +1,9 @@ +- [ ] advertise the notifications channel in well-known +- [ ] advertise the notifications channel in HTTP headers +- [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud +- [ ] add notifications controller +- [ ] handle register requests - this must validate that the requestor has read access to the resource; +- [ ] handle unregister requests +- [ ] implement function to get subscription in SolidWebHook +- [ ] add actor to notifications +- [ ] add UUID to notifications From dab4b9386a2724ebc579a85ca18f6b85016590c1 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:50:57 +0200 Subject: [PATCH 37/91] update todo --- solid/TODO.Notifications | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications index eaaf6669..9af93c0b 100644 --- a/solid/TODO.Notifications +++ b/solid/TODO.Notifications @@ -2,8 +2,14 @@ - [ ] advertise the notifications channel in HTTP headers - [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud - [ ] add notifications controller +- [ ] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry + - [ ] handle register requests - this must validate that the requestor has read access to the resource; -- [ ] handle unregister requests +- [ ] handle unregister requests - only the webid that subscribed should be able to unsubscribe - [ ] implement function to get subscription in SolidWebHook - [ ] add actor to notifications - [ ] add UUID to notifications + +- [ ] Add support for the rate limit feature. +- [ ] create a solid-notifications-lastsent database table - columns are subscription_id and lastsent; +- [ ] how can we stop sending notifications when read access was revoked? From e398328f55b04c81d423c7d19f163e1e900d2e50 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 15:53:11 +0200 Subject: [PATCH 38/91] use dev branch --- solid/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/composer.json b/solid/composer.json index 3cef351f..42617404 100644 --- a/solid/composer.json +++ b/solid/composer.json @@ -30,7 +30,7 @@ "pdsinterop/flysystem-nextcloud":"^0.2", "pdsinterop/flysystem-rdf": "^0.5", "pdsinterop/solid-auth": "^0.7", - "pdsinterop/solid-crud": "^0.6", + "pdsinterop/solid-crud": "dev-feature/notificationsInterface", "psr/log" : "^1.1" }, "require-dev": { From 14b2673b6bd3192699cdd3aca740a1af4e34578d Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 16:47:10 +0200 Subject: [PATCH 39/91] update composer.lock --- solid/composer.lock | 150 +++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 73 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index 876aaff9..4c9ccf3c 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5d63fb5c291e8f16e3e0b5cd42de117c", + "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", "packages": [ { "name": "arc/base", @@ -433,25 +433,24 @@ }, { "name": "laminas/laminas-diactoros", - "version": "2.14.0", + "version": "2.17.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28" + "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6cb35f61913f06b2c91075db00f67cfd78869e28", - "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", + "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", "shasum": "" }, "require": { - "php": "^7.3 || ~8.0.0 || ~8.1.0", + "php": "^7.4 || ~8.0.0 || ~8.1.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0" }, "conflict": { - "phpspec/prophecy": "<1.9.0", "zendframework/zend-diactoros": "*" }, "provide": { @@ -464,10 +463,9 @@ "ext-gd": "*", "ext-libxml": "*", "http-interop/http-factory-tests": "^0.9.0", - "laminas/laminas-coding-standard": "~2.3.0", + "laminas/laminas-coding-standard": "^2.4.0", "php-http/psr7-integration-tests": "^1.1.1", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^9.5.23", "psalm/plugin-phpunit": "^0.17.0", "vimeo/psalm": "^4.24.0" }, @@ -528,7 +526,7 @@ "type": "community_bridge" } ], - "time": "2022-07-28T12:23:48+00:00" + "time": "2022-08-30T17:01:46+00:00" }, { "name": "lcobucci/clock", @@ -1010,37 +1008,38 @@ }, { "name": "league/uri", - "version": "6.7.1", + "version": "6.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea" + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", - "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/a700b4656e4c54371b799ac61e300ab25a2d1d39", + "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39", "shasum": "" }, "require": { "ext-json": "*", "league/uri-interfaces": "^2.3", - "php": "^7.4 || ^8.0", - "psr/http-message": "^1.0" + "php": "^8.1", + "psr/http-message": "^1.0.1" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^v3.3.2", - "nyholm/psr7": "^1.5", - "php-http/psr7-integration-tests": "^1.1", - "phpstan/phpstan": "^1.2.0", + "friendsofphp/php-cs-fixer": "^v3.9.5", + "nyholm/psr7": "^1.5.1", + "php-http/psr7-integration-tests": "^1.1.1", + "phpbench/phpbench": "^1.2.6", + "phpstan/phpstan": "^1.8.5", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpunit/phpunit": "^9.5.10", - "psr/http-factory": "^1.0" + "phpstan/phpstan-phpunit": "^1.1.1", + "phpstan/phpstan-strict-rules": "^1.4.3", + "phpunit/phpunit": "^9.5.24", + "psr/http-factory": "^1.0.1" }, "suggest": { "ext-fileinfo": "Needed to create Data URI from a filepath", @@ -1097,7 +1096,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.7.1" + "source": "https://github.com/thephpleague/uri/tree/6.8.0" }, "funding": [ { @@ -1105,7 +1104,7 @@ "type": "github" } ], - "time": "2022-06-29T09:48:18+00:00" + "time": "2022-09-13T19:58:47+00:00" }, { "name": "league/uri-interfaces", @@ -1537,16 +1536,16 @@ }, { "name": "pdsinterop/solid-crud", - "version": "v0.6.0", + "version": "dev-feature/notificationsInterface", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474" + "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/d68164b50b6b575a7f634aa87374fba3ef84a838", + "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838", "shasum": "" }, "require": { @@ -1561,6 +1560,9 @@ "psr/http-message": "^1.0", "textalk/websocket": "^1.5" }, + "require-dev": { + "phpunit/phpunit": "^9" + }, "type": "library", "autoload": { "psr-4": { @@ -1574,9 +1576,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.6.0" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" }, - "time": "2022-08-24T08:13:54+00:00" + "time": "2022-09-16T13:37:05+00:00" }, { "name": "pietercolpaert/hardf", @@ -2263,16 +2265,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -2313,9 +2315,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" }, - "time": "2022-05-31T20:59:12+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "phar-io/manifest", @@ -2430,16 +2432,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.16", + "version": "9.2.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", "shasum": "" }, "require": { @@ -2495,7 +2497,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" }, "funding": [ { @@ -2503,7 +2505,7 @@ "type": "github" } ], - "time": "2022-08-20T05:26:47+00:00" + "time": "2022-08-30T12:24:04+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2748,16 +2750,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.23", + "version": "9.5.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34" + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", "shasum": "" }, "require": { @@ -2786,7 +2788,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.1", "sebastian/version": "^3.0.2" }, "suggest": { @@ -2830,7 +2832,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" }, "funding": [ { @@ -2842,7 +2844,7 @@ "type": "github" } ], - "time": "2022-08-22T14:01:36+00:00" + "time": "2022-08-30T07:42:16+00:00" }, { "name": "sebastian/cli-parser", @@ -3013,16 +3015,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -3075,7 +3077,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -3083,7 +3085,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -3273,16 +3275,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -3338,7 +3340,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -3346,7 +3348,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -3701,16 +3703,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", "shasum": "" }, "require": { @@ -3722,7 +3724,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3745,7 +3747,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" }, "funding": [ { @@ -3753,7 +3755,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2022-09-12T14:47:03+00:00" }, { "name": "sebastian/version", @@ -3861,7 +3863,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "pdsinterop/solid-crud": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3870,5 +3874,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.1.0" } From 734938ddba95133aac864544c917fefb83c8490b Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 16 Sep 2022 16:47:51 +0200 Subject: [PATCH 40/91] whitespace fix --- solid/lib/Notifications/SolidNotifications.php | 2 +- solid/lib/Notifications/SolidPubSub.php | 2 +- solid/lib/Notifications/SolidWebHook.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/lib/Notifications/SolidNotifications.php b/solid/lib/Notifications/SolidNotifications.php index 9fb640e8..dac12069 100644 --- a/solid/lib/Notifications/SolidNotifications.php +++ b/solid/lib/Notifications/SolidNotifications.php @@ -21,4 +21,4 @@ public function send($path, $type) { $notification->send($path, $type); } } - } \ No newline at end of file + } diff --git a/solid/lib/Notifications/SolidPubSub.php b/solid/lib/Notifications/SolidPubSub.php index 081e6f81..07291cf5 100644 --- a/solid/lib/Notifications/SolidPubSub.php +++ b/solid/lib/Notifications/SolidPubSub.php @@ -26,4 +26,4 @@ public function send($path, $type) { throw new Exception('Could not write to pubsub server', 502, $exception); } } - } \ No newline at end of file + } diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php index 225a8b85..d379bb5f 100644 --- a/solid/lib/Notifications/SolidWebHook.php +++ b/solid/lib/Notifications/SolidWebHook.php @@ -54,4 +54,4 @@ private function createUpdatePayload($path, $type) { return json_encode($payload); } - } \ No newline at end of file + } From c7fa2363da3bd2a42c3faa09daaf2cc2f9171fa5 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:11:46 +0200 Subject: [PATCH 41/91] add database schema for webhook registration --- .../Version000000Date20220919084800.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 solid/lib/Migration/Version000000Date20220919084800.php diff --git a/solid/lib/Migration/Version000000Date20220919084800.php b/solid/lib/Migration/Version000000Date20220919084800.php new file mode 100644 index 00000000..82d71197 --- /dev/null +++ b/solid/lib/Migration/Version000000Date20220919084800.php @@ -0,0 +1,54 @@ +hasTable('solid_notifications_webhooks')) { + $table = $schema->createTable('solid_notifications_webhooks'); + // id, webid, path, url, expiry + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + ]); + $table->addColumn('webid', 'string', [ + 'notnull' => true, + 'length' => 2048 + ]); + $table->addColumn('path', 'string', [ + 'notnull' => true, + 'length' => 2048, + ]); + $table->addColumn('url', 'string', [ + 'notnull' => true, + 'length' => 2048, + ]); + $table->addColumn('expiry', 'string', [ + 'notnull' => true, + 'length' => 2048, + ]); + + $table->setPrimaryKey(['id']); + $table->addIndex(['webid'], 'solid_notifications_webhooks_webid_index'); + $table->addIndex(['path'], 'solid_notifications_webhooks_path_index'); + } + return $schema; + } +} From fc585a2e6324940870fc454a37f7d29781b4e484 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:39:38 +0200 Subject: [PATCH 42/91] typofix --- solid/lib/Controller/CalendarController.php | 2 +- solid/lib/Controller/ContactsController.php | 2 +- solid/lib/Controller/ProfileController.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/lib/Controller/CalendarController.php b/solid/lib/Controller/CalendarController.php index 7cd59b7f..0a4dff47 100644 --- a/solid/lib/Controller/CalendarController.php +++ b/solid/lib/Controller/CalendarController.php @@ -127,7 +127,7 @@ public function handleRequest($userId, $path) { $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); $notifications = new SolidNotifications(); - $this->resourceServer->setNotifications($notification); + $this->resourceServer->setNotifications($notifications); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ContactsController.php b/solid/lib/Controller/ContactsController.php index 1f4359b4..63c0852b 100644 --- a/solid/lib/Controller/ContactsController.php +++ b/solid/lib/Controller/ContactsController.php @@ -127,7 +127,7 @@ public function handleRequest($userId, $path) { $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); $notifications = new SolidNotifications(); - $this->resourceServer->setNotifications($notification); + $this->resourceServer->setNotifications($notifications); try { $webId = $this->DPop->getWebId($request); diff --git a/solid/lib/Controller/ProfileController.php b/solid/lib/Controller/ProfileController.php index caec62ef..eb27a0ec 100644 --- a/solid/lib/Controller/ProfileController.php +++ b/solid/lib/Controller/ProfileController.php @@ -144,7 +144,7 @@ public function handleRequest($userId, $path) { $this->resourceServer->setBaseUrl($baseUrl); $this->WAC->setBaseUrl($baseUrl); $notifications = new SolidNotifications(); - $this->resourceServer->setNotifications($notification); + $this->resourceServer->setNotifications($notifications); if ($request->getHeaderLine("DPop")) { try { From f70d1ad77f832bc40c56198a60de26cbc3ae9cec Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:39:46 +0200 Subject: [PATCH 43/91] update TODO --- solid/TODO.Notifications | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications index 9af93c0b..06c47ad2 100644 --- a/solid/TODO.Notifications +++ b/solid/TODO.Notifications @@ -1,15 +1,19 @@ +TODO: - [ ] advertise the notifications channel in well-known - [ ] advertise the notifications channel in HTTP headers - [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud -- [ ] add notifications controller -- [ ] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry +- [ ] add notifications controller - [ ] handle register requests - this must validate that the requestor has read access to the resource; - [ ] handle unregister requests - only the webid that subscribed should be able to unsubscribe - [ ] implement function to get subscription in SolidWebHook + +Backlog / later: - [ ] add actor to notifications - [ ] add UUID to notifications - - [ ] Add support for the rate limit feature. - [ ] create a solid-notifications-lastsent database table - columns are subscription_id and lastsent; - [ ] how can we stop sending notifications when read access was revoked? + +Done: +- [v] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry From a0b5b4da6717f101ccfe543a4d647483a2883f52 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 09:41:43 +0200 Subject: [PATCH 44/91] fix variable names (url -> webhookUrl) to be more clear --- solid/lib/Notifications/SolidWebHook.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php index d379bb5f..c67778b9 100644 --- a/solid/lib/Notifications/SolidWebHook.php +++ b/solid/lib/Notifications/SolidWebHook.php @@ -5,14 +5,14 @@ class SolidWebhook implements SolidNotificationsInterface { public function send($path, $type) { $subscribedUrls = $this->getSubscribedUrls($path, $type); - foreach ($subscribedUrls as $url) { - $this->postUpdate($url, $path, $type); + foreach ($subscribedUrls as $webhookUrl) { + $this->postUpdate($webhookUrl, $path, $type); } } private function getSubscribedUrls($path, $type) { return []; // FIXME: Read this from the subscriptions } - private function postUpdate($url, $path, $type) { + private function postUpdate($webhookUrl, $path, $type) { try { $postData = $this->createUpdatePayload($path, $type); $opts = array('http' => @@ -23,7 +23,7 @@ private function postUpdate($url, $path, $type) { ) ); $context = stream_context_create($opts); - $result = file_get_contents($webhook, false, $context); + $result = file_get_contents($webhookUrl, false, $context); } catch (\Exception $exception) { throw new Exception('Could not write to webhook server', 502, $exception); } From 7854b643d59dc1abf50afd658532438890b09810 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 13:40:41 +0200 Subject: [PATCH 45/91] rename to change case --- .../Notifications/{SolidWebHook.php => SolidWebHook.php.moved} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename solid/lib/Notifications/{SolidWebHook.php => SolidWebHook.php.moved} (100%) diff --git a/solid/lib/Notifications/SolidWebHook.php b/solid/lib/Notifications/SolidWebHook.php.moved similarity index 100% rename from solid/lib/Notifications/SolidWebHook.php rename to solid/lib/Notifications/SolidWebHook.php.moved From 7cb93959f4357825a8dd28dabe9057d92f19acd5 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 13:41:01 +0200 Subject: [PATCH 46/91] rename to change case --- solid/lib/Notifications/SolidWebhook.php | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 solid/lib/Notifications/SolidWebhook.php diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php new file mode 100644 index 00000000..c67778b9 --- /dev/null +++ b/solid/lib/Notifications/SolidWebhook.php @@ -0,0 +1,57 @@ +getSubscribedUrls($path, $type); + foreach ($subscribedUrls as $webhookUrl) { + $this->postUpdate($webhookUrl, $path, $type); + } + } + private function getSubscribedUrls($path, $type) { + return []; // FIXME: Read this from the subscriptions + } + private function postUpdate($webhookUrl, $path, $type) { + try { + $postData = $this->createUpdatePayload($path, $type); + $opts = array('http' => + array( + 'method' => 'POST', + 'header' => 'Content-Type: application/ld+json', + 'content' => $postData + ) + ); + $context = stream_context_create($opts); + $result = file_get_contents($webhookUrl, false, $context); + } catch (\Exception $exception) { + throw new Exception('Could not write to webhook server', 502, $exception); + } + } + private function createUpdatePayload($path, $type) { + //$updateId = "urn:uuid:"; + //$actor = ""; + $object = [ + "id" => $path, + "type" => [ + "http://www.w3.org/ns/ldp#Resource" + ] + ]; + $state = "1234-5678-90ab-cdef-12345678"; + $published = date(DATE_ISO8601); + $payload = [ + "@context" => [ + "https://www.w3.org/ns/activitystreams", + "https://www.w3.org/ns/solid/notification/v1" + ], + // "id":$updateId, + // "actor" : [$actor], + "type" => [$type], + "object" => $object, + // "state" : $state + "published" => $published + ]; + + return json_encode($payload); + } + } From 780ce4185e391ee674d245aa161ab856724e7144 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 13:41:18 +0200 Subject: [PATCH 47/91] removed --- .../lib/Notifications/SolidWebHook.php.moved | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 solid/lib/Notifications/SolidWebHook.php.moved diff --git a/solid/lib/Notifications/SolidWebHook.php.moved b/solid/lib/Notifications/SolidWebHook.php.moved deleted file mode 100644 index c67778b9..00000000 --- a/solid/lib/Notifications/SolidWebHook.php.moved +++ /dev/null @@ -1,57 +0,0 @@ -getSubscribedUrls($path, $type); - foreach ($subscribedUrls as $webhookUrl) { - $this->postUpdate($webhookUrl, $path, $type); - } - } - private function getSubscribedUrls($path, $type) { - return []; // FIXME: Read this from the subscriptions - } - private function postUpdate($webhookUrl, $path, $type) { - try { - $postData = $this->createUpdatePayload($path, $type); - $opts = array('http' => - array( - 'method' => 'POST', - 'header' => 'Content-Type: application/ld+json', - 'content' => $postData - ) - ); - $context = stream_context_create($opts); - $result = file_get_contents($webhookUrl, false, $context); - } catch (\Exception $exception) { - throw new Exception('Could not write to webhook server', 502, $exception); - } - } - private function createUpdatePayload($path, $type) { - //$updateId = "urn:uuid:"; - //$actor = ""; - $object = [ - "id" => $path, - "type" => [ - "http://www.w3.org/ns/ldp#Resource" - ] - ]; - $state = "1234-5678-90ab-cdef-12345678"; - $published = date(DATE_ISO8601); - $payload = [ - "@context" => [ - "https://www.w3.org/ns/activitystreams", - "https://www.w3.org/ns/solid/notification/v1" - ], - // "id":$updateId, - // "actor" : [$actor], - "type" => [$type], - "object" => $object, - // "state" : $state - "published" => $published - ]; - - return json_encode($payload); - } - } From f65ed5513bf2b29eabfb83db05a366da51a559bf Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:49:20 +0200 Subject: [PATCH 48/91] Revert "use dev branch" This reverts commit 1559a3d8bea70886464b47318c62b99396dc02d6. --- solid/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/composer.json b/solid/composer.json index 42617404..3cef351f 100644 --- a/solid/composer.json +++ b/solid/composer.json @@ -30,7 +30,7 @@ "pdsinterop/flysystem-nextcloud":"^0.2", "pdsinterop/flysystem-rdf": "^0.5", "pdsinterop/solid-auth": "^0.7", - "pdsinterop/solid-crud": "dev-feature/notificationsInterface", + "pdsinterop/solid-crud": "^0.6", "psr/log" : "^1.1" }, "require-dev": { From 9f578be63de0348b6121c6b620834dca36c4df83 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:49:29 +0200 Subject: [PATCH 49/91] Revert "update composer.lock" This reverts commit 625cdb59b811f80b88b20d4d5a07b0811409017f. --- solid/composer.lock | 150 +++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 77 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index 4c9ccf3c..876aaff9 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", + "content-hash": "5d63fb5c291e8f16e3e0b5cd42de117c", "packages": [ { "name": "arc/base", @@ -433,24 +433,25 @@ }, { "name": "laminas/laminas-diactoros", - "version": "2.17.0", + "version": "2.14.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5" + "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", - "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6cb35f61913f06b2c91075db00f67cfd78869e28", + "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28", "shasum": "" }, "require": { - "php": "^7.4 || ~8.0.0 || ~8.1.0", + "php": "^7.3 || ~8.0.0 || ~8.1.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0" }, "conflict": { + "phpspec/prophecy": "<1.9.0", "zendframework/zend-diactoros": "*" }, "provide": { @@ -463,9 +464,10 @@ "ext-gd": "*", "ext-libxml": "*", "http-interop/http-factory-tests": "^0.9.0", - "laminas/laminas-coding-standard": "^2.4.0", + "laminas/laminas-coding-standard": "~2.3.0", "php-http/psr7-integration-tests": "^1.1.1", - "phpunit/phpunit": "^9.5.23", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", "psalm/plugin-phpunit": "^0.17.0", "vimeo/psalm": "^4.24.0" }, @@ -526,7 +528,7 @@ "type": "community_bridge" } ], - "time": "2022-08-30T17:01:46+00:00" + "time": "2022-07-28T12:23:48+00:00" }, { "name": "lcobucci/clock", @@ -1008,38 +1010,37 @@ }, { "name": "league/uri", - "version": "6.8.0", + "version": "6.7.1", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39" + "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/a700b4656e4c54371b799ac61e300ab25a2d1d39", - "reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", + "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", "shasum": "" }, "require": { "ext-json": "*", "league/uri-interfaces": "^2.3", - "php": "^8.1", - "psr/http-message": "^1.0.1" + "php": "^7.4 || ^8.0", + "psr/http-message": "^1.0" }, "conflict": { "league/uri-schemes": "^1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^v3.9.5", - "nyholm/psr7": "^1.5.1", - "php-http/psr7-integration-tests": "^1.1.1", - "phpbench/phpbench": "^1.2.6", - "phpstan/phpstan": "^1.8.5", + "friendsofphp/php-cs-fixer": "^v3.3.2", + "nyholm/psr7": "^1.5", + "php-http/psr7-integration-tests": "^1.1", + "phpstan/phpstan": "^1.2.0", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.1.1", - "phpstan/phpstan-strict-rules": "^1.4.3", - "phpunit/phpunit": "^9.5.24", - "psr/http-factory": "^1.0.1" + "phpstan/phpstan-phpunit": "^1.0.0", + "phpstan/phpstan-strict-rules": "^1.1.0", + "phpunit/phpunit": "^9.5.10", + "psr/http-factory": "^1.0" }, "suggest": { "ext-fileinfo": "Needed to create Data URI from a filepath", @@ -1096,7 +1097,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.8.0" + "source": "https://github.com/thephpleague/uri/tree/6.7.1" }, "funding": [ { @@ -1104,7 +1105,7 @@ "type": "github" } ], - "time": "2022-09-13T19:58:47+00:00" + "time": "2022-06-29T09:48:18+00:00" }, { "name": "league/uri-interfaces", @@ -1536,16 +1537,16 @@ }, { "name": "pdsinterop/solid-crud", - "version": "dev-feature/notificationsInterface", + "version": "v0.6.0", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838" + "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/d68164b50b6b575a7f634aa87374fba3ef84a838", - "reference": "d68164b50b6b575a7f634aa87374fba3ef84a838", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", + "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", "shasum": "" }, "require": { @@ -1560,9 +1561,6 @@ "psr/http-message": "^1.0", "textalk/websocket": "^1.5" }, - "require-dev": { - "phpunit/phpunit": "^9" - }, "type": "library", "autoload": { "psr-4": { @@ -1576,9 +1574,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.6.0" }, - "time": "2022-09-16T13:37:05+00:00" + "time": "2022-08-24T08:13:54+00:00" }, { "name": "pietercolpaert/hardf", @@ -2265,16 +2263,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -2315,9 +2313,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "phar-io/manifest", @@ -2432,16 +2430,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "9.2.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", "shasum": "" }, "require": { @@ -2497,7 +2495,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" }, "funding": [ { @@ -2505,7 +2503,7 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2022-08-20T05:26:47+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2750,16 +2748,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.24", + "version": "9.5.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" + "reference": "888556852e7e9bbeeedb9656afe46118765ade34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", + "reference": "888556852e7e9bbeeedb9656afe46118765ade34", "shasum": "" }, "require": { @@ -2788,7 +2786,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.1", + "sebastian/type": "^3.0", "sebastian/version": "^3.0.2" }, "suggest": { @@ -2832,7 +2830,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" }, "funding": [ { @@ -2844,7 +2842,7 @@ "type": "github" } ], - "time": "2022-08-30T07:42:16+00:00" + "time": "2022-08-22T14:01:36+00:00" }, { "name": "sebastian/cli-parser", @@ -3015,16 +3013,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { @@ -3077,7 +3075,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" }, "funding": [ { @@ -3085,7 +3083,7 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2020-10-26T15:49:45+00:00" }, { "name": "sebastian/complexity", @@ -3275,16 +3273,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.5", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -3340,7 +3338,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { @@ -3348,7 +3346,7 @@ "type": "github" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", @@ -3703,16 +3701,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", "shasum": "" }, "require": { @@ -3724,7 +3722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -3747,7 +3745,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" }, "funding": [ { @@ -3755,7 +3753,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", @@ -3863,9 +3861,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "pdsinterop/solid-crud": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3874,5 +3870,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From 6e7bb87510502ef1b1198d8a07ca3572e840e862 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:54:24 +0200 Subject: [PATCH 50/91] rename table --- solid/composer.json | 2 +- solid/composer.lock | 23 +++++++++++-------- .../Version000000Date20220919084800.php | 11 ++++----- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/solid/composer.json b/solid/composer.json index 3cef351f..42617404 100644 --- a/solid/composer.json +++ b/solid/composer.json @@ -30,7 +30,7 @@ "pdsinterop/flysystem-nextcloud":"^0.2", "pdsinterop/flysystem-rdf": "^0.5", "pdsinterop/solid-auth": "^0.7", - "pdsinterop/solid-crud": "^0.6", + "pdsinterop/solid-crud": "dev-feature/notificationsInterface", "psr/log" : "^1.1" }, "require-dev": { diff --git a/solid/composer.lock b/solid/composer.lock index 876aaff9..90b84237 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5d63fb5c291e8f16e3e0b5cd42de117c", + "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", "packages": [ { "name": "arc/base", @@ -1537,16 +1537,16 @@ }, { "name": "pdsinterop/solid-crud", - "version": "v0.6.0", + "version": "dev-feature/notificationsInterface", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474" + "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", - "reference": "f7a892c6f3a85f5e618e30e2ddb87b211f3c5474", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", + "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", "shasum": "" }, "require": { @@ -1561,6 +1561,9 @@ "psr/http-message": "^1.0", "textalk/websocket": "^1.5" }, + "require-dev": { + "phpunit/phpunit": "^9" + }, "type": "library", "autoload": { "psr-4": { @@ -1574,9 +1577,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.6.0" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" }, - "time": "2022-08-24T08:13:54+00:00" + "time": "2022-09-19T06:45:41+00:00" }, { "name": "pietercolpaert/hardf", @@ -3861,7 +3864,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "pdsinterop/solid-crud": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3870,5 +3875,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.1.0" } diff --git a/solid/lib/Migration/Version000000Date20220919084800.php b/solid/lib/Migration/Version000000Date20220919084800.php index 82d71197..3db0c258 100644 --- a/solid/lib/Migration/Version000000Date20220919084800.php +++ b/solid/lib/Migration/Version000000Date20220919084800.php @@ -10,7 +10,6 @@ use OCP\Migration\IOutput; class Version000000Date20220919084800 extends SimpleMigrationStep { - /** * @param IOutput $output * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` @@ -21,14 +20,14 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); - if (!$schema->hasTable('solid_notifications_webhooks')) { - $table = $schema->createTable('solid_notifications_webhooks'); + if (!$schema->hasTable('solid_webhooks')) { + $table = $schema->createTable('solid_webhooks'); // id, webid, path, url, expiry $table->addColumn('id', 'integer', [ 'autoincrement' => true, 'notnull' => true, ]); - $table->addColumn('webid', 'string', [ + $table->addColumn('web_id', 'string', [ 'notnull' => true, 'length' => 2048 ]); @@ -46,8 +45,8 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt ]); $table->setPrimaryKey(['id']); - $table->addIndex(['webid'], 'solid_notifications_webhooks_webid_index'); - $table->addIndex(['path'], 'solid_notifications_webhooks_path_index'); + $table->addIndex(['web_id'], 'solid_webhooks_web_id_index'); + $table->addIndex(['path'], 'solid_webhooks_path_index'); } return $schema; } From 291786d562aaa2129fd5cb4a2f5bd75596276b77 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:56:27 +0200 Subject: [PATCH 51/91] add entity and Db mapper --- solid/lib/Db/SolidWebhook.php | 25 +++++++++++++ solid/lib/Db/SolidWebhookMapper.php | 58 +++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 solid/lib/Db/SolidWebhook.php create mode 100644 solid/lib/Db/SolidWebhookMapper.php diff --git a/solid/lib/Db/SolidWebhook.php b/solid/lib/Db/SolidWebhook.php new file mode 100644 index 00000000..330d027a --- /dev/null +++ b/solid/lib/Db/SolidWebhook.php @@ -0,0 +1,25 @@ + $this->id, + 'webId' => $this->webId, + 'path' => $this->path, + 'url' => $this->url, + 'expiry' => $this->expiry + ]; + } +} diff --git a/solid/lib/Db/SolidWebhookMapper.php b/solid/lib/Db/SolidWebhookMapper.php new file mode 100644 index 00000000..fa35ec76 --- /dev/null +++ b/solid/lib/Db/SolidWebhookMapper.php @@ -0,0 +1,58 @@ +db->getQueryBuilder(); + $qb->select('*') + ->from('solid_webhooks') + ->where($qb->expr()->eq('web_id', $qb->createNamedParameter($webId))) + ->andWhere($qb->expr()->eq('path', $qb->createNamedParameter($path))); + return $this->findEntity($qb); + } + + /** + * @param string $webId + * @return array + */ + public function findAll(string $webId): array { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('solid_webhooks') + ->where($qb->expr()->eq('web_id', $qb->createNamedParameter($webId))); + return $this->findEntities($qb); + } + + /** + * @param string $path + * @return array + */ + public function findByPath(string $path): array { + /* @var $qb IQueryBuilder */ + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('solid_webhooks') + ->where($qb->expr()->eq('path', $qb->createNamedParameter($path))); + return $this->findEntities($qb); + } +} From 6881cb638382fc2edf345c71aea5615bbaa0cc03 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:56:58 +0200 Subject: [PATCH 52/91] add solidwebhook service --- solid/lib/Service/SolidWebhookNotFound.php | 6 ++ solid/lib/Service/SolidWebhookService.php | 65 ++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 solid/lib/Service/SolidWebhookNotFound.php create mode 100644 solid/lib/Service/SolidWebhookService.php diff --git a/solid/lib/Service/SolidWebhookNotFound.php b/solid/lib/Service/SolidWebhookNotFound.php new file mode 100644 index 00000000..7a06886f --- /dev/null +++ b/solid/lib/Service/SolidWebhookNotFound.php @@ -0,0 +1,6 @@ +mapper = $mapper; + } + + public function findAll(string $webId): array { + return $this->mapper->findAll($webId); + } + + public function findByPath(string $path): array { + return $this->mapper->findByPath($path); + } + + private function handleException(Exception $e): void { + if ($e instanceof DoesNotExistException || + $e instanceof MultipleObjectsReturnedException) { + throw new SolidWebhookNotFound($e->getMessage()); + } else { + throw $e; + } + } + + public function find($webId, $path) { + try { + return $this->mapper->find($webId, $path); + } catch (Exception $e) { + $this->handleException($e); + } + } + + public function create($webId, $path, $url, $expiry) { + $webhook = new SolidWebhook(); + $webhook->setWebId($webId); + $webhook->setPath($path); + $webHook->setUrl($url); + $webHook->setExpiry($expiry); + return $this->mapper->insert($note); + } + + public function delete($webId, $path) { + try { + $webhook = $this->mapper->find($webId, $path); + $this->mapper->delete($webhook); + return $webhook; + } catch (Exception $e) { + $this->handleException($e); + } + } +} From d7652f8354160e92e93e8c20a061c3ef05c6d2e7 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 15:57:35 +0200 Subject: [PATCH 53/91] add SolidWebhook controller --- .../lib/Controller/SolidWebhookController.php | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 solid/lib/Controller/SolidWebhookController.php diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php new file mode 100644 index 00000000..8e6cdae8 --- /dev/null +++ b/solid/lib/Controller/SolidWebhookController.php @@ -0,0 +1,188 @@ +config = new \OCA\Solid\ServerConfig($config, $urlGenerator, $userManager); + $this->rootFolder = $rootFolder; + $this->request = $request; + $this->urlGenerator = $urlGenerator; + $this->session = $session; + $this->webhookService = $webhookService; + + $this->DPop = new DPop(); + try { + $this->webId = $this->DPop->getWebId($request); + } catch(\Exception $e) { + $response = $this->resourceServer->getResponse()->withStatus(409, "Invalid token"); + return $this->respond($response); + } + } + + /** + * @PublicPage + * @NoAdminRequired + * @NoCSRFRequired + */ + public function listWebhooks(): DataResponse { + return new DataResponse($this->webhookService->findAll($this->webId)); + } + + /** + * @PublicPage + * @NoAdminRequired + * @NoCSRFRequired + */ + public function register(string $targetUrl, string $webhookUrl, string $expiry): DataResponse { + // FIXME: Validate WAC read access to the target URL for $this->webId + if ($this->checkReadAccess($targetUrl)) { + return new DataResponse($this->webhookService->create($this->webId, $targetUrl, $webhookUrl, $expiry)); + } + } + + /** + * @PublicPage + * @NoAdminRequired + * @NoCSRFRequired + */ + public function unregister(string $targetUrl): DataResponse { + return $this->handleNotFound(function () use ($targetUrl) { + return $this->webhookService->delete($this->webId, $targetUrl); + }); + } + + + private function getFileSystem() { + // Create the Nextcloud Adapter + $adapter = new \Pdsinterop\Flysystem\Adapter\Nextcloud($this->solidFolder); + $graph = new \EasyRdf\Graph(); + + // Create Formats objects + $formats = new \Pdsinterop\Rdf\Formats(); + + $serverUri = "https://" . $this->rawRequest->getServerParams()["SERVER_NAME"] . $this->rawRequest->getServerParams()["REQUEST_URI"]; // FIXME: doublecheck that this is the correct url; + + // Create the RDF Adapter + $rdfAdapter = new \Pdsinterop\Rdf\Flysystem\Adapter\Rdf( + $adapter, + $graph, + $formats, + $serverUri + ); + + $filesystem = new \League\Flysystem\Filesystem($rdfAdapter); + + $filesystem->addPlugin(new \Pdsinterop\Rdf\Flysystem\Plugin\AsMime($formats)); + + $plugin = new \Pdsinterop\Rdf\Flysystem\Plugin\ReadRdf($graph); + $filesystem->addPlugin($plugin); + + return $filesystem; + } + + private function getStorageUrl($userId) { + $storageUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.storage.handleHead", array("userId" => $userId, "path" => "foo"))); + $storageUrl = preg_replace('/foo$/', '', $storageUrl); + return $storageUrl; + } + private function getAppBaseUrl($userId) { + $appBaseUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.app.appLauncher")); + return $appBaseUrl; + } + private function initializeStorage($userId) { + $this->userFolder = $this->rootFolder->getUserFolder($userId); + $this->solidFolder = $this->userFolder->get("solid"); + $this->filesystem = $this->getFileSystem(); + } + + private function parseTargetUrl($targetUrl) { + // targetUrl = https://nextcloud.server/solid/@alice/storage/foo/bar + $appBaseUrl = $this->getAppBaseUrl(); // https://nextcloud.server/solid/ + $internalUrl = str_replace($appBaseUrl, '', $targetUrl); // @alice/storage/foo/bar + $pathicles = explode($internalUrl, "/"); + $userId = $pathicles[0]; // alice + + $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ + $storagePath = str_replace($storageUrl, '/', $targetUrl); // /foo/bar + return array("userId" => $userId, "path", $storagePath); + } + + private function createGetRequest($targetUrl) { + $serverParams = []; + $fileParams = []; + $method = "GET"; + $body = null; + $headers = []; + + return new \Laminas\Diactoros\ServerRequest( + $serverParams, + $fileParams, + $targetUrl, + $method, + $body, + $headers + ); + } + + private function checkReadAccess($targetUrl) { + // split out $targetUrl into $userId and $path https://nextcloud.server/solid/@alice/storage/foo/bar + // - userId in this case is the pod owner (not the one doing the request). (alice) + // - path is the path within the storage pod (/foo/bar) + $target = $this->parseTargetUrl($targetUrl); + $userId = $target["userId"]; + $path = $target["path"]; + + $this->initializeStorage($userId); + $this->WAC = new WAC($this->filesystem); + + $baseUrl = $this->getStorageUrl($userId); + $this->WAC->setBaseUrl($baseUrl); + + $serverParams = []; + $fileParams = []; + + $request = $this->createGetRequest($targetUrl); + if (!$this->WAC->isAllowed($request, $this->webId)) { // Deny if we don't have read grants on the URL; + return false; + } + return true; + } +} From a7fe5d5610b482f51657e79ef3e969ca9ee06a4d Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:00:09 +0200 Subject: [PATCH 54/91] add routes --- solid/appinfo/routes.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solid/appinfo/routes.php b/solid/appinfo/routes.php index 89011912..c000caf6 100644 --- a/solid/appinfo/routes.php +++ b/solid/appinfo/routes.php @@ -51,6 +51,10 @@ ['name' => 'contacts#handlePatch', 'url' => '/@{userId}/contacts{path}', 'verb' => 'PATCH', 'requirements' => array('path' => '.+')], ['name' => 'contacts#handleHead', 'url' => '/@{userId}/contacts{path}', 'verb' => 'HEAD', 'requirements' => array('path' => '.+')], + ['name' => 'solidwebhook#listWebhooks', 'url' => '/webhook/list', 'verb' => 'GET'], + ['name' => 'solidwebhook#register', 'url' => '/webhook/register', 'verb' => 'POST'], + ['name' => 'solidwebhook#unregister', 'url' => '/webhook/unregister', 'verb' => 'POST'], + ['name' => 'app#appLauncher', 'url' => '/', 'verb' => 'GET'], ] ]; From 01f560388ac1ece914e2480b41aa81f5f55eae12 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:02:53 +0200 Subject: [PATCH 55/91] whitespace - fix sniff --- solid/lib/Service/SolidWebhookService.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/solid/lib/Service/SolidWebhookService.php b/solid/lib/Service/SolidWebhookService.php index 2e93da1f..60263a86 100644 --- a/solid/lib/Service/SolidWebhookService.php +++ b/solid/lib/Service/SolidWebhookService.php @@ -11,7 +11,6 @@ use OCA\Solid\Db\SolidWebhookMapper; class SolidWebhookService { - /** @var SolidWebhookMapper */ private $mapper; @@ -28,8 +27,10 @@ public function findByPath(string $path): array { } private function handleException(Exception $e): void { - if ($e instanceof DoesNotExistException || - $e instanceof MultipleObjectsReturnedException) { + if ( + $e instanceof DoesNotExistException || + $e instanceof MultipleObjectsReturnedException + ) { throw new SolidWebhookNotFound($e->getMessage()); } else { throw $e; From b65b2ad962e612038386fd587171e31859b6d8e8 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:22:21 +0200 Subject: [PATCH 56/91] update namespace --- solid/lib/Notifications/SolidNotifications.php | 2 +- solid/lib/Notifications/SolidPubSub.php | 2 +- solid/lib/Notifications/SolidWebhook.php | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/solid/lib/Notifications/SolidNotifications.php b/solid/lib/Notifications/SolidNotifications.php index dac12069..89ee428a 100644 --- a/solid/lib/Notifications/SolidNotifications.php +++ b/solid/lib/Notifications/SolidNotifications.php @@ -3,7 +3,7 @@ use OCA\Solid\Notifications\SolidPubSub; use OCA\Solid\Notifications\SolidWebhook; - use Pdsinterop\Solid\SolidNotificationsInterface; + use Pdsinterop\Solid\SolidNotifications\SolidNotificationsInterface; class SolidNotifications implements SolidNotificationsInterface { diff --git a/solid/lib/Notifications/SolidPubSub.php b/solid/lib/Notifications/SolidPubSub.php index 07291cf5..e0acaf4c 100644 --- a/solid/lib/Notifications/SolidPubSub.php +++ b/solid/lib/Notifications/SolidPubSub.php @@ -2,7 +2,7 @@ namespace OCA\Solid\Notifications; use WebSocket\Client; - use Pdsinterop\Solid\SolidNotificationsInterface; + use Pdsinterop\Solid\SolidNotifications\SolidNotificationsInterface; class SolidPubSub implements SolidNotificationsInterface { diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index c67778b9..b5483d78 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -1,6 +1,8 @@ Date: Mon, 19 Sep 2022 16:44:49 +0200 Subject: [PATCH 57/91] update solid-crud --- solid/composer.lock | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index 90b84237..c0f600a8 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -1541,12 +1541,12 @@ "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2" + "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", - "reference": "e2bd63594caa7f29bfd9d6c3699a6e921655d2b2", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", + "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", "shasum": "" }, "require": { @@ -1567,7 +1567,8 @@ "type": "library", "autoload": { "psr-4": { - "Pdsinterop\\Solid\\Resources\\": "src/" + "Pdsinterop\\Solid\\Resources\\": "src/", + "Pdsinterop\\Solid\\SolidNotifications\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1579,7 +1580,7 @@ "issues": "https://github.com/pdsinterop/php-solid-crud/issues", "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" }, - "time": "2022-09-19T06:45:41+00:00" + "time": "2022-09-19T14:41:18+00:00" }, { "name": "pietercolpaert/hardf", From beef4e7c2a9f77cbc1ae85fbe62ba3af1aed12f3 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 16:58:50 +0200 Subject: [PATCH 58/91] fix case --- solid/appinfo/routes.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/appinfo/routes.php b/solid/appinfo/routes.php index c000caf6..c106a0e4 100644 --- a/solid/appinfo/routes.php +++ b/solid/appinfo/routes.php @@ -51,9 +51,9 @@ ['name' => 'contacts#handlePatch', 'url' => '/@{userId}/contacts{path}', 'verb' => 'PATCH', 'requirements' => array('path' => '.+')], ['name' => 'contacts#handleHead', 'url' => '/@{userId}/contacts{path}', 'verb' => 'HEAD', 'requirements' => array('path' => '.+')], - ['name' => 'solidwebhook#listWebhooks', 'url' => '/webhook/list', 'verb' => 'GET'], - ['name' => 'solidwebhook#register', 'url' => '/webhook/register', 'verb' => 'POST'], - ['name' => 'solidwebhook#unregister', 'url' => '/webhook/unregister', 'verb' => 'POST'], + ['name' => 'solidWebhook#listWebhooks', 'url' => '/webhook/list', 'verb' => 'GET'], + ['name' => 'solidWebhook#register', 'url' => '/webhook/register', 'verb' => 'POST'], + ['name' => 'solidWebhook#unregister', 'url' => '/webhook/unregister', 'verb' => 'POST'], ['name' => 'app#appLauncher', 'url' => '/', 'verb' => 'GET'], ] From f9f02ba4158fd9dae9169642cff0a93dc6ddb689 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 19 Sep 2022 17:00:52 +0200 Subject: [PATCH 59/91] use raw request instead of nextcloud request object --- solid/lib/Controller/SolidWebhookController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 8e6cdae8..7f0603da 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -50,7 +50,8 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request $this->DPop = new DPop(); try { - $this->webId = $this->DPop->getWebId($request); + $rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); + $this->webId = $this->DPop->getWebId($rawRequest); } catch(\Exception $e) { $response = $this->resourceServer->getResponse()->withStatus(409, "Invalid token"); return $this->respond($response); From b433b0199437ed8c0fd6e5a6a2c0ea6469f69800 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 09:39:51 +0200 Subject: [PATCH 60/91] bugfixing drycoded controller --- solid/lib/Controller/SolidWebhookController.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 7f0603da..122b29f2 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -53,8 +53,7 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request $rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); $this->webId = $this->DPop->getWebId($rawRequest); } catch(\Exception $e) { - $response = $this->resourceServer->getResponse()->withStatus(409, "Invalid token"); - return $this->respond($response); + return new PlainResponse("Invalid token", 409); } } @@ -124,7 +123,7 @@ private function getStorageUrl($userId) { $storageUrl = preg_replace('/foo$/', '', $storageUrl); return $storageUrl; } - private function getAppBaseUrl($userId) { + private function getAppBaseUrl() { $appBaseUrl = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.app.appLauncher")); return $appBaseUrl; } @@ -138,12 +137,15 @@ private function parseTargetUrl($targetUrl) { // targetUrl = https://nextcloud.server/solid/@alice/storage/foo/bar $appBaseUrl = $this->getAppBaseUrl(); // https://nextcloud.server/solid/ $internalUrl = str_replace($appBaseUrl, '', $targetUrl); // @alice/storage/foo/bar - $pathicles = explode($internalUrl, "/"); + $pathicles = explode("/", $internalUrl); $userId = $pathicles[0]; // alice $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ $storagePath = str_replace($storageUrl, '/', $targetUrl); // /foo/bar - return array("userId" => $userId, "path", $storagePath); + return array( + "userId" => $userId, + "path" => $storagePath + ); } private function createGetRequest($targetUrl) { From 21ea0c246370817bcc3e7ab5a927e74d81544786 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 09:45:41 +0200 Subject: [PATCH 61/91] more bugfixes for drycoded --- solid/lib/Controller/SolidWebhookController.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 122b29f2..12134781 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -50,8 +50,8 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request $this->DPop = new DPop(); try { - $rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); - $this->webId = $this->DPop->getWebId($rawRequest); + $this->rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); + $this->webId = $this->DPop->getWebId($this->rawRequest); } catch(\Exception $e) { return new PlainResponse("Invalid token", 409); } @@ -138,9 +138,9 @@ private function parseTargetUrl($targetUrl) { $appBaseUrl = $this->getAppBaseUrl(); // https://nextcloud.server/solid/ $internalUrl = str_replace($appBaseUrl, '', $targetUrl); // @alice/storage/foo/bar $pathicles = explode("/", $internalUrl); - $userId = $pathicles[0]; // alice - - $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ + $userId = $pathicles[0]; // @alice + $userId = preg_replace("/^@/", "", $userId); // alice + $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ $storagePath = str_replace($storageUrl, '/', $targetUrl); // /foo/bar return array( "userId" => $userId, From 0c1e8d9781de54af7ecef3a5b6431555c8918153 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:32:04 +0200 Subject: [PATCH 62/91] use memory to provide a stream --- solid/lib/Controller/SolidWebhookController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 12134781..d0971014 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -152,7 +152,7 @@ private function createGetRequest($targetUrl) { $serverParams = []; $fileParams = []; $method = "GET"; - $body = null; + $body = 'php://memory'; $headers = []; return new \Laminas\Diactoros\ServerRequest( From bf42c33c8226058ecc330a7327226f174c900de4 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:32:27 +0200 Subject: [PATCH 63/91] make $id public --- solid/lib/Db/SolidWebhook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/lib/Db/SolidWebhook.php b/solid/lib/Db/SolidWebhook.php index 330d027a..8fcab4ac 100644 --- a/solid/lib/Db/SolidWebhook.php +++ b/solid/lib/Db/SolidWebhook.php @@ -7,7 +7,7 @@ use OCP\AppFramework\Db\Entity; class SolidWebhook extends Entity implements JsonSerializable { - protected $id; + public $id; protected $path; protected $webId; protected $url; From 106730533c235b279c5f202dba312dcc82c212ba Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:32:50 +0200 Subject: [PATCH 64/91] typofixes --- solid/lib/Service/SolidWebhookService.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solid/lib/Service/SolidWebhookService.php b/solid/lib/Service/SolidWebhookService.php index 60263a86..b8c9dc61 100644 --- a/solid/lib/Service/SolidWebhookService.php +++ b/solid/lib/Service/SolidWebhookService.php @@ -49,9 +49,9 @@ public function create($webId, $path, $url, $expiry) { $webhook = new SolidWebhook(); $webhook->setWebId($webId); $webhook->setPath($path); - $webHook->setUrl($url); - $webHook->setExpiry($expiry); - return $this->mapper->insert($note); + $webhook->setUrl($url); + $webhook->setExpiry($expiry); + return $this->mapper->insert($webhook); } public function delete($webId, $path) { From 644f0d3a01f1171c4843945200d8a994ffb933bb Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:55:49 +0200 Subject: [PATCH 65/91] add error handler --- solid/lib/Controller/SolidWebhookController.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index d0971014..36ca4cfe 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -2,6 +2,7 @@ namespace OCA\Solid\Controller; +use Closure; use OCA\Solid\AppInfo\Application; use OCA\Solid\Service\SolidWebhookService; use OCA\Solid\ServerConfig; @@ -52,6 +53,7 @@ public function __construct($AppName, IRootFolder $rootFolder, IRequest $request try { $this->rawRequest = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); $this->webId = $this->DPop->getWebId($this->rawRequest); + // FIXME: Should we handle webhooks for 'public'? } catch(\Exception $e) { return new PlainResponse("Invalid token", 409); } @@ -188,4 +190,13 @@ private function checkReadAccess($targetUrl) { } return true; } + + private function handleNotFound(Closure $callback): DataResponse { + try { + return new DataResponse($callback()); + } catch (SolidWebhookNotFound $e) { + $message = ['message' => $e->getMessage()]; + return new DataResponse($message, Http::STATUS_NOT_FOUND); + } + } } From 1c17c8b40af978e82aa75e00bb62463faf34da8c Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 11:56:26 +0200 Subject: [PATCH 66/91] add code to fetch webhooks --- solid/lib/Notifications/SolidWebhook.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index b5483d78..e07d13e4 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -5,14 +5,23 @@ class SolidWebhook implements SolidNotificationsInterface { + public function __construct(\OCA\Solid\Service\SolidWebhookService $webhookService) { + $this->webhookService = $webhookService; + } + public function send($path, $type) { - $subscribedUrls = $this->getSubscribedUrls($path, $type); - foreach ($subscribedUrls as $webhookUrl) { - $this->postUpdate($webhookUrl, $path, $type); + $webhooks = $this->getWebhooks($path); + foreach ($webhooks as $webhook) { + try { + $this->postUpdate($webhook['url'], $path, $type); + } catch(\Exception $e) { + // FIXME: add retry code here? + } } } - private function getSubscribedUrls($path, $type) { - return []; // FIXME: Read this from the subscriptions + private function getWebhooks($path, $type) { + $urls = $this->webhookService->findByPath($path); + return $urls; } private function postUpdate($webhookUrl, $path, $type) { try { From 833702e81eca5c0850e9aae8c542f65807f66570 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 15:42:18 +0200 Subject: [PATCH 67/91] update TODO --- solid/TODO.Notifications | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications index 06c47ad2..09731ecb 100644 --- a/solid/TODO.Notifications +++ b/solid/TODO.Notifications @@ -2,11 +2,7 @@ TODO: - [ ] advertise the notifications channel in well-known - [ ] advertise the notifications channel in HTTP headers - [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud - -- [ ] add notifications controller -- [ ] handle register requests - this must validate that the requestor has read access to the resource; -- [ ] handle unregister requests - only the webid that subscribed should be able to unsubscribe -- [ ] implement function to get subscription in SolidWebHook +- [ ] implement function to get subscription in SolidWebhook Backlog / later: - [ ] add actor to notifications @@ -17,3 +13,6 @@ Backlog / later: Done: - [v] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry +- [v] add notifications controller +- [v] handle register requests - this must validate that the requestor has read access to the resource; +- [v] handle unregister requests - only the webid that subscribed should be able to unsubscribe From 5bc53b1c647e860c903b18adeb6fddac3a711b18 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 16:19:20 +0200 Subject: [PATCH 68/91] add webhook services to dependancy injection --- solid/lib/AppInfo/Application.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/solid/lib/AppInfo/Application.php b/solid/lib/AppInfo/Application.php index ed895307..f7477677 100644 --- a/solid/lib/AppInfo/Application.php +++ b/solid/lib/AppInfo/Application.php @@ -42,6 +42,18 @@ public function __construct(array $urlParams = []) { // executed in the order that it is registered $container->registerMiddleware(SolidCorsMiddleware::class); + + $container->registerService(SolidWebhookService::class, function($c): SolidWebhookService { + return new SolidWebhookService( + $c->query(SolidWebhookMapper::class) + ); + }); + + $container->registerService(SolidWebhookMapper::class, function($c): SolidWebhookMapper { + return new SolidWebhookMapper( + $c->get(IDBConnection::class) + ); + }); } public function register(IRegistrationContext $context): void { From e3e6385d12efe32cf0dedb085307c53a93401fc4 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 16:20:03 +0200 Subject: [PATCH 69/91] grab solid webhook service from dependancy injection --- solid/lib/Notifications/SolidWebhook.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index e07d13e4..97342cad 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -1,12 +1,14 @@ webhookService = $webhookService; + public function __construct() { + $app = new \OCP\AppFramework\App('solid'); + $this->webhookService = $app->getContainer()->get(SolidWebhookService::class); } public function send($path, $type) { From 4743056d7020f8543f450b4ec3549169d3d786f6 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 26 Sep 2022 16:43:18 +0200 Subject: [PATCH 70/91] add cors header for wellknown --- solid/lib/WellKnown/OpenIdConfigurationHandler.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solid/lib/WellKnown/OpenIdConfigurationHandler.php b/solid/lib/WellKnown/OpenIdConfigurationHandler.php index 16dfbdd3..fffa812c 100644 --- a/solid/lib/WellKnown/OpenIdConfigurationHandler.php +++ b/solid/lib/WellKnown/OpenIdConfigurationHandler.php @@ -116,6 +116,8 @@ private function respond($response) { $result->addHeader($header, $value); } } + + $result->addHeader("Access-Control-Allow-Origin", "*"); $result->setStatus($statusCode); return $result; } From 3915af327c2bb1c01e23eec5c20b00f18d5a4169 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 28 Sep 2022 11:10:07 +0200 Subject: [PATCH 71/91] reinstate updates-via header --- solid/TODO.Notifications | 3 ++- solid/lib/Middleware/SolidCorsMiddleware.php | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications index 09731ecb..16b24dfc 100644 --- a/solid/TODO.Notifications +++ b/solid/TODO.Notifications @@ -1,7 +1,6 @@ TODO: - [ ] advertise the notifications channel in well-known - [ ] advertise the notifications channel in HTTP headers -- [ ] reinstate the updates-via header in HEAD requests, which was removed from solid-crud - [ ] implement function to get subscription in SolidWebhook Backlog / later: @@ -10,9 +9,11 @@ Backlog / later: - [ ] Add support for the rate limit feature. - [ ] create a solid-notifications-lastsent database table - columns are subscription_id and lastsent; - [ ] how can we stop sending notifications when read access was revoked? +- [ ] use a background process to send notifications so they are out of bound with requests Done: - [v] create a solid-notifications-subscription database table - columns should have: id, webid, path, url, expiry - [v] add notifications controller - [v] handle register requests - this must validate that the requestor has read access to the resource; - [v] handle unregister requests - only the webid that subscribed should be able to unsubscribe +- [v] reinstate the updates-via header in HEAD requests, which was removed from solid-crud diff --git a/solid/lib/Middleware/SolidCorsMiddleware.php b/solid/lib/Middleware/SolidCorsMiddleware.php index 13dd59e6..48f3b674 100644 --- a/solid/lib/Middleware/SolidCorsMiddleware.php +++ b/solid/lib/Middleware/SolidCorsMiddleware.php @@ -34,6 +34,11 @@ public function afterController($controller, $methodName, Response $response) { $response->addHeader('Access-Control-Expose-Headers', $corsExposeHeaders); $response->addHeader('Accept-Patch', 'text/n3'); + if (strtolower($methodName) == "head") { + $pubsub = getenv("PUBSUB_URL") ?: "http://pubsub:8080"; + $response->addHeader('updates-via', $pubsub); + } + return $response; } } From 6311a45978b7a9a850b5724fa133341695921252 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 28 Sep 2022 11:26:00 +0200 Subject: [PATCH 72/91] fix arguments --- solid/lib/Notifications/SolidWebhook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index 97342cad..7fdb5624 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -21,7 +21,7 @@ public function send($path, $type) { } } } - private function getWebhooks($path, $type) { + private function getWebhooks($path) { $urls = $this->webhookService->findByPath($path); return $urls; } From 34d2627729d03bc69144eb1a8a83a246ad1e4623 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 28 Sep 2022 11:45:28 +0200 Subject: [PATCH 73/91] methodname here is the function name, not the HTTP method --- solid/lib/Middleware/SolidCorsMiddleware.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/solid/lib/Middleware/SolidCorsMiddleware.php b/solid/lib/Middleware/SolidCorsMiddleware.php index 48f3b674..85c227b5 100644 --- a/solid/lib/Middleware/SolidCorsMiddleware.php +++ b/solid/lib/Middleware/SolidCorsMiddleware.php @@ -34,10 +34,8 @@ public function afterController($controller, $methodName, Response $response) { $response->addHeader('Access-Control-Expose-Headers', $corsExposeHeaders); $response->addHeader('Accept-Patch', 'text/n3'); - if (strtolower($methodName) == "head") { - $pubsub = getenv("PUBSUB_URL") ?: "http://pubsub:8080"; - $response->addHeader('updates-via', $pubsub); - } + $pubsub = getenv("PUBSUB_URL") ?: "http://pubsub:8080"; + $response->addHeader('updates-via', $pubsub); return $response; } From 76480c957a377d944a5ce5bacab720b775187c66 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 28 Sep 2022 12:03:58 +0200 Subject: [PATCH 74/91] make the values public --- solid/lib/Db/SolidWebhook.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solid/lib/Db/SolidWebhook.php b/solid/lib/Db/SolidWebhook.php index 8fcab4ac..6945b760 100644 --- a/solid/lib/Db/SolidWebhook.php +++ b/solid/lib/Db/SolidWebhook.php @@ -8,10 +8,10 @@ class SolidWebhook extends Entity implements JsonSerializable { public $id; - protected $path; - protected $webId; - protected $url; - protected $expiry; + public $path; + public $webId; + public $url; + public $expiry; public function jsonSerialize(): array { return [ From a2ef63408a8cc63bf5a2fc33e5f197ef162337ed Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 28 Sep 2022 12:16:55 +0200 Subject: [PATCH 75/91] use the object, skip verify on ssl for now --- solid/lib/Notifications/SolidWebhook.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index 7fdb5624..bcbb24a4 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -15,7 +15,7 @@ public function send($path, $type) { $webhooks = $this->getWebhooks($path); foreach ($webhooks as $webhook) { try { - $this->postUpdate($webhook['url'], $path, $type); + $this->postUpdate($webhook->{'url'}, $path, $type); } catch(\Exception $e) { // FIXME: add retry code here? } @@ -28,11 +28,15 @@ private function getWebhooks($path) { private function postUpdate($webhookUrl, $path, $type) { try { $postData = $this->createUpdatePayload($path, $type); - $opts = array('http' => - array( + $opts = array( + 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/ld+json', 'content' => $postData + ), + 'ssl' => array( + 'verify_peer' => false, // FIXME: Do we need to be more strict here? + 'verify_peer_name' => false ) ); $context = stream_context_create($opts); From c1ed57ff33ff6aed764525d0436f4dc8d381499c Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 28 Sep 2022 16:06:58 +0200 Subject: [PATCH 76/91] align naming with the specs --- solid/TODO.Notifications | 2 +- .../lib/Controller/SolidWebhookController.php | 45 ++++++++++++------- solid/lib/Db/SolidWebhook.php | 10 ++--- solid/lib/Db/SolidWebhookMapper.php | 12 ++--- .../Version000000Date20220919084800.php | 12 ++--- solid/lib/Notifications/SolidWebhook.php | 18 ++++---- solid/lib/Service/SolidWebhookService.php | 19 ++++---- 7 files changed, 61 insertions(+), 57 deletions(-) diff --git a/solid/TODO.Notifications b/solid/TODO.Notifications index 16b24dfc..8e1c276f 100644 --- a/solid/TODO.Notifications +++ b/solid/TODO.Notifications @@ -1,7 +1,6 @@ TODO: - [ ] advertise the notifications channel in well-known - [ ] advertise the notifications channel in HTTP headers -- [ ] implement function to get subscription in SolidWebhook Backlog / later: - [ ] add actor to notifications @@ -17,3 +16,4 @@ Done: - [v] handle register requests - this must validate that the requestor has read access to the resource; - [v] handle unregister requests - only the webid that subscribed should be able to unsubscribe - [v] reinstate the updates-via header in HEAD requests, which was removed from solid-crud +- [v] implement function to get subscription in SolidWebhook diff --git a/solid/lib/Controller/SolidWebhookController.php b/solid/lib/Controller/SolidWebhookController.php index 36ca4cfe..977bf0fc 100644 --- a/solid/lib/Controller/SolidWebhookController.php +++ b/solid/lib/Controller/SolidWebhookController.php @@ -73,10 +73,15 @@ public function listWebhooks(): DataResponse { * @NoAdminRequired * @NoCSRFRequired */ - public function register(string $targetUrl, string $webhookUrl, string $expiry): DataResponse { - // FIXME: Validate WAC read access to the target URL for $this->webId - if ($this->checkReadAccess($targetUrl)) { - return new DataResponse($this->webhookService->create($this->webId, $targetUrl, $webhookUrl, $expiry)); + public function register(string $topic, string $target): DataResponse { + if (!$this->isValidWebhookTarget($target)) { + return new DataResponse("Error: invalid webhook target", 422); + } + + if ($this->checkReadAccess($topic)) { + return new DataResponse($this->webhookService->create($this->webId, $topic, $target)); + } else { + return new DataResponse("Error: denied access", 401); } } @@ -85,12 +90,18 @@ public function register(string $targetUrl, string $webhookUrl, string $expiry): * @NoAdminRequired * @NoCSRFRequired */ - public function unregister(string $targetUrl): DataResponse { - return $this->handleNotFound(function () use ($targetUrl) { - return $this->webhookService->delete($this->webId, $targetUrl); + public function unregister(string $topic): DataResponse { + return $this->handleNotFound(function () use ($topic) { + return $this->webhookService->delete($this->webId, $topic); }); } + private function isValidWebhookTarget($target) { + if (!preg_match("|^https://|", $target)) { + return false; + } + return true; + } private function getFileSystem() { // Create the Nextcloud Adapter @@ -135,22 +146,22 @@ private function initializeStorage($userId) { $this->filesystem = $this->getFileSystem(); } - private function parseTargetUrl($targetUrl) { - // targetUrl = https://nextcloud.server/solid/@alice/storage/foo/bar + private function parseTopic($topic) { + // topic = https://nextcloud.server/solid/@alice/storage/foo/bar $appBaseUrl = $this->getAppBaseUrl(); // https://nextcloud.server/solid/ - $internalUrl = str_replace($appBaseUrl, '', $targetUrl); // @alice/storage/foo/bar + $internalUrl = str_replace($appBaseUrl, '', $topic); // @alice/storage/foo/bar $pathicles = explode("/", $internalUrl); $userId = $pathicles[0]; // @alice $userId = preg_replace("/^@/", "", $userId); // alice $storageUrl = $this->getStorageUrl($userId); // https://nextcloud.server/solid/@alice/storage/ - $storagePath = str_replace($storageUrl, '/', $targetUrl); // /foo/bar + $storagePath = str_replace($storageUrl, '/', $topic); // /foo/bar return array( "userId" => $userId, "path" => $storagePath ); } - private function createGetRequest($targetUrl) { + private function createGetRequest($topic) { $serverParams = []; $fileParams = []; $method = "GET"; @@ -160,18 +171,18 @@ private function createGetRequest($targetUrl) { return new \Laminas\Diactoros\ServerRequest( $serverParams, $fileParams, - $targetUrl, + $topic, $method, $body, $headers ); } - private function checkReadAccess($targetUrl) { - // split out $targetUrl into $userId and $path https://nextcloud.server/solid/@alice/storage/foo/bar + private function checkReadAccess($topic) { + // split out $topic into $userId and $path https://nextcloud.server/solid/@alice/storage/foo/bar // - userId in this case is the pod owner (not the one doing the request). (alice) // - path is the path within the storage pod (/foo/bar) - $target = $this->parseTargetUrl($targetUrl); + $target = $this->parseTopic($topic); $userId = $target["userId"]; $path = $target["path"]; @@ -184,7 +195,7 @@ private function checkReadAccess($targetUrl) { $serverParams = []; $fileParams = []; - $request = $this->createGetRequest($targetUrl); + $request = $this->createGetRequest($topic); if (!$this->WAC->isAllowed($request, $this->webId)) { // Deny if we don't have read grants on the URL; return false; } diff --git a/solid/lib/Db/SolidWebhook.php b/solid/lib/Db/SolidWebhook.php index 6945b760..824fb1b7 100644 --- a/solid/lib/Db/SolidWebhook.php +++ b/solid/lib/Db/SolidWebhook.php @@ -8,18 +8,16 @@ class SolidWebhook extends Entity implements JsonSerializable { public $id; - public $path; + public $topic; public $webId; - public $url; - public $expiry; + public $target; public function jsonSerialize(): array { return [ 'id' => $this->id, 'webId' => $this->webId, - 'path' => $this->path, - 'url' => $this->url, - 'expiry' => $this->expiry + 'topic' => $this->topic, + 'target' => $this->target ]; } } diff --git a/solid/lib/Db/SolidWebhookMapper.php b/solid/lib/Db/SolidWebhookMapper.php index fa35ec76..cfae6699 100644 --- a/solid/lib/Db/SolidWebhookMapper.php +++ b/solid/lib/Db/SolidWebhookMapper.php @@ -15,18 +15,18 @@ public function __construct(IDBConnection $db) { /** * @param string $webId - * @param string $path + * @param string $topic * @return Entity|SolidWebhook * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws DoesNotExistException */ - public function find(string $webId, string $path): SolidWebhook { + public function find(string $webId, string $topic): SolidWebhook { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $qb->select('*') ->from('solid_webhooks') ->where($qb->expr()->eq('web_id', $qb->createNamedParameter($webId))) - ->andWhere($qb->expr()->eq('path', $qb->createNamedParameter($path))); + ->andWhere($qb->expr()->eq('topic', $qb->createNamedParameter($topic))); return $this->findEntity($qb); } @@ -44,15 +44,15 @@ public function findAll(string $webId): array { } /** - * @param string $path + * @param string $topic * @return array */ - public function findByPath(string $path): array { + public function findByTopic(string $topic): array { /* @var $qb IQueryBuilder */ $qb = $this->db->getQueryBuilder(); $qb->select('*') ->from('solid_webhooks') - ->where($qb->expr()->eq('path', $qb->createNamedParameter($path))); + ->where($qb->expr()->eq('topic', $qb->createNamedParameter($topic))); return $this->findEntities($qb); } } diff --git a/solid/lib/Migration/Version000000Date20220919084800.php b/solid/lib/Migration/Version000000Date20220919084800.php index 3db0c258..22a6fa03 100644 --- a/solid/lib/Migration/Version000000Date20220919084800.php +++ b/solid/lib/Migration/Version000000Date20220919084800.php @@ -22,7 +22,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt if (!$schema->hasTable('solid_webhooks')) { $table = $schema->createTable('solid_webhooks'); - // id, webid, path, url, expiry + // id, webid, topic, target $table->addColumn('id', 'integer', [ 'autoincrement' => true, 'notnull' => true, @@ -31,22 +31,18 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt 'notnull' => true, 'length' => 2048 ]); - $table->addColumn('path', 'string', [ + $table->addColumn('topic', 'string', [ 'notnull' => true, 'length' => 2048, ]); - $table->addColumn('url', 'string', [ - 'notnull' => true, - 'length' => 2048, - ]); - $table->addColumn('expiry', 'string', [ + $table->addColumn('target', 'string', [ 'notnull' => true, 'length' => 2048, ]); $table->setPrimaryKey(['id']); $table->addIndex(['web_id'], 'solid_webhooks_web_id_index'); - $table->addIndex(['path'], 'solid_webhooks_path_index'); + $table->addIndex(['target'], 'solid_webhooks_target_index'); } return $schema; } diff --git a/solid/lib/Notifications/SolidWebhook.php b/solid/lib/Notifications/SolidWebhook.php index bcbb24a4..00df1acf 100644 --- a/solid/lib/Notifications/SolidWebhook.php +++ b/solid/lib/Notifications/SolidWebhook.php @@ -11,23 +11,23 @@ public function __construct() { $this->webhookService = $app->getContainer()->get(SolidWebhookService::class); } - public function send($path, $type) { - $webhooks = $this->getWebhooks($path); + public function send($topic, $type) { + $webhooks = $this->getWebhooks($topic); foreach ($webhooks as $webhook) { try { - $this->postUpdate($webhook->{'url'}, $path, $type); + $this->postUpdate($webhook->{'target'}, $topic, $type); } catch(\Exception $e) { // FIXME: add retry code here? } } } - private function getWebhooks($path) { - $urls = $this->webhookService->findByPath($path); + private function getWebhooks($topic) { + $urls = $this->webhookService->findByTopic($topic); return $urls; } - private function postUpdate($webhookUrl, $path, $type) { + private function postUpdate($webhookUrl, $topic, $type) { try { - $postData = $this->createUpdatePayload($path, $type); + $postData = $this->createUpdatePayload($topic, $type); $opts = array( 'http' => array( 'method' => 'POST', @@ -45,11 +45,11 @@ private function postUpdate($webhookUrl, $path, $type) { throw new Exception('Could not write to webhook server', 502, $exception); } } - private function createUpdatePayload($path, $type) { + private function createUpdatePayload($topic, $type) { //$updateId = "urn:uuid:"; //$actor = ""; $object = [ - "id" => $path, + "id" => $topic, "type" => [ "http://www.w3.org/ns/ldp#Resource" ] diff --git a/solid/lib/Service/SolidWebhookService.php b/solid/lib/Service/SolidWebhookService.php index b8c9dc61..32469a90 100644 --- a/solid/lib/Service/SolidWebhookService.php +++ b/solid/lib/Service/SolidWebhookService.php @@ -22,8 +22,8 @@ public function findAll(string $webId): array { return $this->mapper->findAll($webId); } - public function findByPath(string $path): array { - return $this->mapper->findByPath($path); + public function findByTopic(string $topic): array { + return $this->mapper->findByTopic($topic); } private function handleException(Exception $e): void { @@ -37,26 +37,25 @@ private function handleException(Exception $e): void { } } - public function find($webId, $path) { + public function find($webId, $topic) { try { - return $this->mapper->find($webId, $path); + return $this->mapper->find($webId, $topic); } catch (Exception $e) { $this->handleException($e); } } - public function create($webId, $path, $url, $expiry) { + public function create($webId, $topic, $target) { $webhook = new SolidWebhook(); $webhook->setWebId($webId); - $webhook->setPath($path); - $webhook->setUrl($url); - $webhook->setExpiry($expiry); + $webhook->setTopic($topic); + $webhook->setTarget($target); return $this->mapper->insert($webhook); } - public function delete($webId, $path) { + public function delete($webId, $topic) { try { - $webhook = $this->mapper->find($webId, $path); + $webhook = $this->mapper->find($webId, $topic); $this->mapper->delete($webhook); return $webhook; } catch (Exception $e) { From b2d59b5ec3f2c2e29c05f5d364e85ce6baf5da92 Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Thu, 29 Sep 2022 08:32:32 +0200 Subject: [PATCH 77/91] Draft handler for /.well-known/solid --- solid/lib/AppInfo/Application.php | 2 ++ solid/lib/WellKnown/SolidHandler.php | 47 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 solid/lib/WellKnown/SolidHandler.php diff --git a/solid/lib/AppInfo/Application.php b/solid/lib/AppInfo/Application.php index f7477677..134cd7ee 100644 --- a/solid/lib/AppInfo/Application.php +++ b/solid/lib/AppInfo/Application.php @@ -11,6 +11,7 @@ use OCA\Solid\Service\UserService; use OCA\Solid\WellKnown\OpenIdConfigurationHandler; +use OCA\Solid\WellKnown\SolidHandler; use OCA\Solid\Middleware\SolidCorsMiddleware; use OCP\AppFramework\App; @@ -58,6 +59,7 @@ public function __construct(array $urlParams = []) { public function register(IRegistrationContext $context): void { $context->registerWellKnownHandler(\OCA\Solid\WellKnown\OpenIdConfigurationHandler::class); + $context->registerWellKnownHandler(\OCA\Solid\WellKnown\SolidHandler::class); /** * Core class wrappers diff --git a/solid/lib/WellKnown/SolidHandler.php b/solid/lib/WellKnown/SolidHandler.php new file mode 100644 index 00000000..c67109cd --- /dev/null +++ b/solid/lib/WellKnown/SolidHandler.php @@ -0,0 +1,47 @@ +urlGenerator = $urlGenerator; + } + + public function handle(string $service, IRequestContext $context, ?IResponse $previousResponse): ?IResponse { + if ($service !== 'solid') { + return $previousResponse; + } + + $body = [ + "@context" => [ + "https://www.w3.org/ns/solid/notification/v1" + ], + "notificationChannel" => [ + [ + "id" => "websocketNotification", + "type" => ["WebSocketSubscription2021"], + "subscription" => "https://websocket.example/subscription", + "feature" => ["state", "rate", "expiration"] + ] + ] + ]; + $result = new JSONResponse($body); + $result->addHeader("Access-Control-Allow-Origin", "*"); + $result->setStatus(200); + return $result; + } +} From 70abe0d8537c7306af5774df78ab1709f822d47f Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Thu, 29 Sep 2022 08:51:11 +0200 Subject: [PATCH 78/91] advertise both websockets and webhooks --- solid/lib/WellKnown/SolidHandler.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/solid/lib/WellKnown/SolidHandler.php b/solid/lib/WellKnown/SolidHandler.php index c67109cd..df61d0ff 100644 --- a/solid/lib/WellKnown/SolidHandler.php +++ b/solid/lib/WellKnown/SolidHandler.php @@ -7,6 +7,7 @@ use OCP\IConfig; use OCP\AppFramework\Http\JSONResponse; +use OCP\Http\WellKnown\GenericResponse; use OCP\Http\WellKnown\IHandler; use OCP\Http\WellKnown\IRequestContext; use OCP\Http\WellKnown\IResponse; @@ -34,14 +35,19 @@ public function handle(string $service, IRequestContext $context, ?IResponse $pr [ "id" => "websocketNotification", "type" => ["WebSocketSubscription2021"], - "subscription" => "https://websocket.example/subscription", - "feature" => ["state", "rate", "expiration"] + "feature" => [] + ], + [ + "id" => "webhookNotification", + "type" => ["WebHookSubscription2022"], + "subscription" => $this->urlGenerator->linkToRoute("solid.soldWebhook.register"), + "feature" => [] ] ] - ]; + ]; $result = new JSONResponse($body); $result->addHeader("Access-Control-Allow-Origin", "*"); $result->setStatus(200); - return $result; + return new GenericResponse($result); } } From fbe31264a49e1fed0d377bd0fec245d5f8f5ee0e Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Thu, 29 Sep 2022 09:05:09 +0200 Subject: [PATCH 79/91] Build in Docker --- .gitignore | 2 + solid/composer.lock | 126 ++++++++++++++++++++++---------------------- 2 files changed, 66 insertions(+), 62 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d8b8e4fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +solid/bin +solid/vendor diff --git a/solid/composer.lock b/solid/composer.lock index c0f600a8..e7ecc634 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -433,25 +433,24 @@ }, { "name": "laminas/laminas-diactoros", - "version": "2.14.0", + "version": "2.17.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28" + "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6cb35f61913f06b2c91075db00f67cfd78869e28", - "reference": "6cb35f61913f06b2c91075db00f67cfd78869e28", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", + "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5", "shasum": "" }, "require": { - "php": "^7.3 || ~8.0.0 || ~8.1.0", + "php": "^7.4 || ~8.0.0 || ~8.1.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0" }, "conflict": { - "phpspec/prophecy": "<1.9.0", "zendframework/zend-diactoros": "*" }, "provide": { @@ -464,10 +463,9 @@ "ext-gd": "*", "ext-libxml": "*", "http-interop/http-factory-tests": "^0.9.0", - "laminas/laminas-coding-standard": "~2.3.0", + "laminas/laminas-coding-standard": "^2.4.0", "php-http/psr7-integration-tests": "^1.1.1", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^9.5.23", "psalm/plugin-phpunit": "^0.17.0", "vimeo/psalm": "^4.24.0" }, @@ -528,7 +526,7 @@ "type": "community_bridge" } ], - "time": "2022-07-28T12:23:48+00:00" + "time": "2022-08-30T17:01:46+00:00" }, { "name": "lcobucci/clock", @@ -1010,16 +1008,16 @@ }, { "name": "league/uri", - "version": "6.7.1", + "version": "6.7.2", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea" + "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", - "reference": "2d7c87a0860f3126a39f44a8a9bf2fed402dcfea", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/d3b50812dd51f3fbf176344cc2981db03d10fe06", + "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06", "shasum": "" }, "require": { @@ -1097,7 +1095,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri/issues", - "source": "https://github.com/thephpleague/uri/tree/6.7.1" + "source": "https://github.com/thephpleague/uri/tree/6.7.2" }, "funding": [ { @@ -1105,7 +1103,7 @@ "type": "github" } ], - "time": "2022-06-29T09:48:18+00:00" + "time": "2022-09-13T19:50:42+00:00" }, { "name": "league/uri-interfaces", @@ -1968,16 +1966,16 @@ }, { "name": "stella-maris/clock", - "version": "0.1.5", + "version": "0.1.6", "source": { "type": "git", "url": "git@gitlab.com:stella-maris/clock.git", - "reference": "447879c53ca0b2a762cdbfba5e76ccf4deca9158" + "reference": "a94228dac03c9a8411198ce8c8dacbbe99c930c3" }, "dist": { "type": "zip", - "url": "https://gitlab.com/api/v4/projects/stella-maris%2Fclock/repository/archive.zip?sha=447879c53ca0b2a762cdbfba5e76ccf4deca9158", - "reference": "447879c53ca0b2a762cdbfba5e76ccf4deca9158", + "url": "https://gitlab.com/api/v4/projects/stella-maris%2Fclock/repository/archive.zip?sha=a94228dac03c9a8411198ce8c8dacbbe99c930c3", + "reference": "a94228dac03c9a8411198ce8c8dacbbe99c930c3", "shasum": "" }, "require": { @@ -2007,7 +2005,7 @@ "point in time", "psr20" ], - "time": "2022-08-05T07:21:25+00:00" + "time": "2022-09-27T15:03:11+00:00" }, { "name": "textalk/websocket", @@ -2267,16 +2265,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -2317,9 +2315,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" }, - "time": "2022-05-31T20:59:12+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "phar-io/manifest", @@ -2434,16 +2432,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.16", + "version": "9.2.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", "shasum": "" }, "require": { @@ -2499,7 +2497,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" }, "funding": [ { @@ -2507,7 +2505,7 @@ "type": "github" } ], - "time": "2022-08-20T05:26:47+00:00" + "time": "2022-08-30T12:24:04+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2752,16 +2750,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.23", + "version": "9.5.25", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34" + "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", + "reference": "3e6f90ca7e3d02025b1d147bd8d4a89fd4ca8a1d", "shasum": "" }, "require": { @@ -2783,14 +2781,14 @@ "phpunit/php-timer": "^5.0.2", "sebastian/cli-parser": "^1.0.1", "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", + "sebastian/comparator": "^4.0.8", "sebastian/diff": "^4.0.3", "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", + "sebastian/exporter": "^4.0.5", "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.2", "sebastian/version": "^3.0.2" }, "suggest": { @@ -2834,7 +2832,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.25" }, "funding": [ { @@ -2844,9 +2842,13 @@ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "time": "2022-08-22T14:01:36+00:00" + "time": "2022-09-25T03:44:45+00:00" }, { "name": "sebastian/cli-parser", @@ -3017,16 +3019,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -3079,7 +3081,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -3087,7 +3089,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -3277,16 +3279,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -3342,7 +3344,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -3350,7 +3352,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -3705,16 +3707,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", "shasum": "" }, "require": { @@ -3726,7 +3728,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3749,7 +3751,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" }, "funding": [ { @@ -3757,7 +3759,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2022-09-12T14:47:03+00:00" }, { "name": "sebastian/version", @@ -3876,5 +3878,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From 4ccaa5deb9c0fb77bb3f969b16292d438187565a Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Thu, 29 Sep 2022 09:29:23 +0200 Subject: [PATCH 80/91] Work around inability to link to solid.solidWebhook.register --- solid/lib/Middleware/SolidCorsMiddleware.php | 1 + solid/lib/WellKnown/SolidHandler.php | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/solid/lib/Middleware/SolidCorsMiddleware.php b/solid/lib/Middleware/SolidCorsMiddleware.php index 85c227b5..5494282a 100644 --- a/solid/lib/Middleware/SolidCorsMiddleware.php +++ b/solid/lib/Middleware/SolidCorsMiddleware.php @@ -36,6 +36,7 @@ public function afterController($controller, $methodName, Response $response) { $pubsub = getenv("PUBSUB_URL") ?: "http://pubsub:8080"; $response->addHeader('updates-via', $pubsub); + $response->addHeader('Link', '; rel="http://www.w3.org/ns/solid#storageDescription"'); return $response; } diff --git a/solid/lib/WellKnown/SolidHandler.php b/solid/lib/WellKnown/SolidHandler.php index df61d0ff..378d7ee2 100644 --- a/solid/lib/WellKnown/SolidHandler.php +++ b/solid/lib/WellKnown/SolidHandler.php @@ -26,7 +26,11 @@ public function handle(string $service, IRequestContext $context, ?IResponse $pr if ($service !== 'solid') { return $previousResponse; } - + $webhooksRegisterEndpoint = $this->urlGenerator->linkToRoute('solid.solidWebhook.register'); + // FIXME: this shouldn't happen: + if (strlen($webhooksRegisterEndpoint) == 0) { + $webhooksRegisterEndpoint = $this->urlGenerator->linkToRoute('solid.app.appLauncher') . 'webhook/register'; + } $body = [ "@context" => [ "https://www.w3.org/ns/solid/notification/v1" @@ -40,7 +44,7 @@ public function handle(string $service, IRequestContext $context, ?IResponse $pr [ "id" => "webhookNotification", "type" => ["WebHookSubscription2022"], - "subscription" => $this->urlGenerator->linkToRoute("solid.soldWebhook.register"), + "subscription" => $webhooksRegisterEndpoint, "feature" => [] ] ] From 712128d8ea4deb196ef259ad24aad5fcd1cd2468 Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Thu, 29 Sep 2022 12:51:26 +0200 Subject: [PATCH 81/91] Code comment about where different headers are added --- solid/lib/Middleware/SolidCorsMiddleware.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solid/lib/Middleware/SolidCorsMiddleware.php b/solid/lib/Middleware/SolidCorsMiddleware.php index 5494282a..71aa2890 100644 --- a/solid/lib/Middleware/SolidCorsMiddleware.php +++ b/solid/lib/Middleware/SolidCorsMiddleware.php @@ -38,6 +38,9 @@ public function afterController($controller, $methodName, Response $response) { $response->addHeader('updates-via', $pubsub); $response->addHeader('Link', '; rel="http://www.w3.org/ns/solid#storageDescription"'); + // Note that apart from these, the Link header with rel="acl" and the WAC-Allow header + // are already added by these lines in vendor/pdsinterop/solid-auth: + // https://github.com/pdsinterop/php-solid-auth/blob/e07c22d/src/WAC.php#L39-L40 return $response; } } From 9cd3c40bac8a818b80ea87ae5c191e20b2e5c6bd Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Thu, 29 Sep 2022 14:17:04 +0200 Subject: [PATCH 82/91] composer.lock --- solid/composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index e7ecc634..a82323e6 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -1302,16 +1302,16 @@ }, { "name": "ml/json-ld", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/lanthaler/JsonLD.git", - "reference": "c74a1aed5979ed1cfb1be35a55a305fd30e30b93" + "reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/c74a1aed5979ed1cfb1be35a55a305fd30e30b93", - "reference": "c74a1aed5979ed1cfb1be35a55a305fd30e30b93", + "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/537e68e87a6bce23e57c575cd5dcac1f67ce25d8", + "reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8", "shasum": "" }, "require": { @@ -1349,9 +1349,9 @@ ], "support": { "issues": "https://github.com/lanthaler/JsonLD/issues", - "source": "https://github.com/lanthaler/JsonLD/tree/1.2.0" + "source": "https://github.com/lanthaler/JsonLD/tree/1.2.1" }, - "time": "2020-06-16T17:45:06+00:00" + "time": "2022-09-29T08:45:17+00:00" }, { "name": "paragonie/random_compat", From 896f9d900c5e79009abdd123c844d67dc00eab6a Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Thu, 29 Sep 2022 14:17:32 +0200 Subject: [PATCH 83/91] Fix issue of overwriting other link headers --- solid/lib/Middleware/SolidCorsMiddleware.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/solid/lib/Middleware/SolidCorsMiddleware.php b/solid/lib/Middleware/SolidCorsMiddleware.php index 71aa2890..3f1c978c 100644 --- a/solid/lib/Middleware/SolidCorsMiddleware.php +++ b/solid/lib/Middleware/SolidCorsMiddleware.php @@ -36,7 +36,12 @@ public function afterController($controller, $methodName, Response $response) { $pubsub = getenv("PUBSUB_URL") ?: "http://pubsub:8080"; $response->addHeader('updates-via', $pubsub); - $response->addHeader('Link', '; rel="http://www.w3.org/ns/solid#storageDescription"'); + $linkHeaders = '; rel="http://www.w3.org/ns/solid#storageDescription"'; + $existingHeaders = $response->getHeaders(); + if (isset($existingHeaders['Link'])) { // careful - this dictionary key is case sensitive here + $linkHeaders .= ', ' . $existingHeaders['Link']; + } + $response->addHeader('Link', $linkHeaders); // Note that apart from these, the Link header with rel="acl" and the WAC-Allow header // are already added by these lines in vendor/pdsinterop/solid-auth: From 22636a6f852d6994454ca97fc968afd9699bd2cb Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Fri, 30 Sep 2022 13:58:42 +0200 Subject: [PATCH 84/91] indentation --- solid/lib/Notifications/SolidNotifications.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solid/lib/Notifications/SolidNotifications.php b/solid/lib/Notifications/SolidNotifications.php index 89ee428a..b492cf7e 100644 --- a/solid/lib/Notifications/SolidNotifications.php +++ b/solid/lib/Notifications/SolidNotifications.php @@ -13,12 +13,12 @@ public function __construct() { $this->notifications = [ new SolidWebhook(), new SolidPubSub($pubsub) - ]; + ]; } public function send($path, $type) { foreach ($this->notifications as $notification) { $notification->send($path, $type); + } } - } } From 5a3b12807e2781717265f1875825fcd42e4e5b6b Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Fri, 30 Sep 2022 14:42:59 +0200 Subject: [PATCH 85/91] add websockets subscribe endpoint --- solid/appinfo/routes.php | 4 +++- .../Controller/SolidWebsocketController.php | 24 +++++++++++++++++++ solid/lib/WellKnown/SolidHandler.php | 7 ++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 solid/lib/Controller/SolidWebsocketController.php diff --git a/solid/appinfo/routes.php b/solid/appinfo/routes.php index c106a0e4..c996d701 100644 --- a/solid/appinfo/routes.php +++ b/solid/appinfo/routes.php @@ -54,7 +54,9 @@ ['name' => 'solidWebhook#listWebhooks', 'url' => '/webhook/list', 'verb' => 'GET'], ['name' => 'solidWebhook#register', 'url' => '/webhook/register', 'verb' => 'POST'], ['name' => 'solidWebhook#unregister', 'url' => '/webhook/unregister', 'verb' => 'POST'], - + + ['name' => 'solidWebsocket#register', 'url' => '/websocket/register', 'verb' => 'POST'], + ['name' => 'app#appLauncher', 'url' => '/', 'verb' => 'GET'], ] ]; diff --git a/solid/lib/Controller/SolidWebsocketController.php b/solid/lib/Controller/SolidWebsocketController.php new file mode 100644 index 00000000..8daef4b7 --- /dev/null +++ b/solid/lib/Controller/SolidWebsocketController.php @@ -0,0 +1,24 @@ + "https://www.w3.org/ns/solid/notification/v1", + "type" => "WebSocketSubscription2021", + "source" => $pubsub . "/?type=WebSocketSubscription2021" + ]); + } +} \ No newline at end of file diff --git a/solid/lib/WellKnown/SolidHandler.php b/solid/lib/WellKnown/SolidHandler.php index 378d7ee2..50265254 100644 --- a/solid/lib/WellKnown/SolidHandler.php +++ b/solid/lib/WellKnown/SolidHandler.php @@ -31,6 +31,12 @@ public function handle(string $service, IRequestContext $context, ?IResponse $pr if (strlen($webhooksRegisterEndpoint) == 0) { $webhooksRegisterEndpoint = $this->urlGenerator->linkToRoute('solid.app.appLauncher') . 'webhook/register'; } + + $websocketsRegisterEndpoint = $this->urlGenerator->linkToRoute('solid.solidWebsocket.register'); + // FIXME: this shouldn't happen: + if (strlen($websocketsRegisterEndpoint) == 0) { + $websocketsRegisterEndpoint = $this->urlGenerator->linkToRoute('solid.app.appLauncher') . 'websocket/register'; + } $body = [ "@context" => [ "https://www.w3.org/ns/solid/notification/v1" @@ -39,6 +45,7 @@ public function handle(string $service, IRequestContext $context, ?IResponse $pr [ "id" => "websocketNotification", "type" => ["WebSocketSubscription2021"], + "subscription" => $websocketsRegisterEndpoint, "feature" => [] ], [ From d0e358f50d9da4d2d71f3957aa344c0ef6316796 Mon Sep 17 00:00:00 2001 From: Ben Peachey Date: Fri, 30 Sep 2022 14:52:38 +0200 Subject: [PATCH 86/91] Update generated composer lock file. --- solid/composer.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index 6b5d9862..7b251cfe 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", + "content-hash": "25870616d02851226edb7d55f5e9e4f0", "packages": [ { "name": "arc/base", @@ -4244,5 +4244,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From dbca1e2ea28cae5705819b66a2e820fb150a6798 Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Fri, 30 Sep 2022 14:53:49 +0200 Subject: [PATCH 87/91] Correct class name --- solid/lib/Controller/SolidWebsocketController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/lib/Controller/SolidWebsocketController.php b/solid/lib/Controller/SolidWebsocketController.php index 8daef4b7..5b64aa39 100644 --- a/solid/lib/Controller/SolidWebsocketController.php +++ b/solid/lib/Controller/SolidWebsocketController.php @@ -5,7 +5,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\DataResponse; -class SolidWebhookController extends Controller +class SolidWebsocketController extends Controller { /** * @PublicPage From 830ff65aabb5ff538c67fa2cd153013aa815a105 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 30 Sep 2022 16:22:58 +0200 Subject: [PATCH 88/91] change order of the test suites to let the wac tests runs --- run-solid-test-suite.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-solid-test-suite.sh b/run-solid-test-suite.sh index 8569ac5e..73e11872 100755 --- a/run-solid-test-suite.sh +++ b/run-solid-test-suite.sh @@ -57,6 +57,6 @@ startPubSub startSolidNextcloud server startSolidNextcloud thirdparty runTests webid-provider -runTests solid-crud runTests web-access-control +runTests solid-crud teardown From 931959e16c92cfac6062410f58328229f657745b Mon Sep 17 00:00:00 2001 From: Ben Peachey Date: Fri, 30 Sep 2022 16:51:35 +0200 Subject: [PATCH 89/91] Update pdsinterop/solid-crud to v0.7 --- solid/composer.json | 4 ++-- solid/composer.lock | 18 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/solid/composer.json b/solid/composer.json index a5ca4654..9697765a 100644 --- a/solid/composer.json +++ b/solid/composer.json @@ -32,8 +32,8 @@ "pdsinterop/flysystem-nextcloud": "^0.2", "pdsinterop/flysystem-rdf": "^0.5", "pdsinterop/solid-auth": "v0.10.1", - "pdsinterop/solid-crud": "dev-feature/notificationsInterface", - "psr/log" : "^1.1" + "pdsinterop/solid-crud": "^0.7.0", + "psr/log": "^1.1" }, "require-dev": { "doctrine/dbal": "*", diff --git a/solid/composer.lock b/solid/composer.lock index 7b251cfe..1e02fb3d 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "25870616d02851226edb7d55f5e9e4f0", + "content-hash": "97758acf86706e9d00cf51f32abbd10d", "packages": [ { "name": "arc/base", @@ -1535,16 +1535,16 @@ }, { "name": "pdsinterop/solid-crud", - "version": "dev-feature/notificationsInterface", + "version": "v0.7.0", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf" + "reference": "4059f0a196e3b12c0809dec29566971aa375f3ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", - "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/4059f0a196e3b12c0809dec29566971aa375f3ad", + "reference": "4059f0a196e3b12c0809dec29566971aa375f3ad", "shasum": "" }, "require": { @@ -1576,9 +1576,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.7.0" }, - "time": "2022-09-19T14:41:18+00:00" + "time": "2022-09-30T14:46:38+00:00" }, { "name": "pietercolpaert/hardf", @@ -4231,9 +4231,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "pdsinterop/solid-crud": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 195f2dcf11416253f09f8ae9b9282f0327f8290b Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 30 Sep 2022 16:58:46 +0200 Subject: [PATCH 90/91] merge from upstream --- solid/composer.lock | 402 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 383 insertions(+), 19 deletions(-) diff --git a/solid/composer.lock b/solid/composer.lock index a82323e6..1e02fb3d 100644 --- a/solid/composer.lock +++ b/solid/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5675e6996cec07511e49d0f6fa4a9e50", + "content-hash": "97758acf86706e9d00cf51f32abbd10d", "packages": [ { "name": "arc/base", @@ -1486,16 +1486,16 @@ }, { "name": "pdsinterop/solid-auth", - "version": "v0.7.0", + "version": "v0.10.1", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-auth.git", - "reference": "d5ae7e9e2b8baa54047e7c3e3be4952345003e9e" + "reference": "c33509edefdbc23b78d745bc4116e04a2b294ab3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-auth/zipball/d5ae7e9e2b8baa54047e7c3e3be4952345003e9e", - "reference": "d5ae7e9e2b8baa54047e7c3e3be4952345003e9e", + "url": "https://api.github.com/repos/pdsinterop/php-solid-auth/zipball/c33509edefdbc23b78d745bc4116e04a2b294ab3", + "reference": "c33509edefdbc23b78d745bc4116e04a2b294ab3", "shasum": "" }, "require": { @@ -1511,7 +1511,7 @@ "require-dev": { "ext-xdebug": "*", "ext-xml": "*", - "phpunit/phpunit": "^8.5 | ^9.5" + "phpunit/phpunit": "^9" }, "type": "library", "autoload": { @@ -1529,22 +1529,22 @@ "description": "OAuth2, OpenID and OIDC for Solid Server implementations.", "support": { "issues": "https://github.com/pdsinterop/php-solid-auth/issues", - "source": "https://github.com/pdsinterop/php-solid-auth/tree/v0.7.0" + "source": "https://github.com/pdsinterop/php-solid-auth/tree/v0.10.1" }, - "time": "2022-08-24T08:26:45+00:00" + "time": "2022-09-30T12:16:20+00:00" }, { "name": "pdsinterop/solid-crud", - "version": "dev-feature/notificationsInterface", + "version": "v0.7.0", "source": { "type": "git", "url": "https://github.com/pdsinterop/php-solid-crud.git", - "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf" + "reference": "4059f0a196e3b12c0809dec29566971aa375f3ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", - "reference": "27fd9c35dbd5fd879958e5114eb4389f0d1fa6cf", + "url": "https://api.github.com/repos/pdsinterop/php-solid-crud/zipball/4059f0a196e3b12c0809dec29566971aa375f3ad", + "reference": "4059f0a196e3b12c0809dec29566971aa375f3ad", "shasum": "" }, "require": { @@ -1576,9 +1576,9 @@ "description": "Solid HTTPS REST API specification compliant implementation for handling Resource CRUD", "support": { "issues": "https://github.com/pdsinterop/php-solid-crud/issues", - "source": "https://github.com/pdsinterop/php-solid-crud/tree/feature/notificationsInterface" + "source": "https://github.com/pdsinterop/php-solid-crud/tree/v0.7.0" }, - "time": "2022-09-19T14:41:18+00:00" + "time": "2022-09-30T14:46:38+00:00" }, { "name": "pietercolpaert/hardf", @@ -1969,12 +1969,12 @@ "version": "0.1.6", "source": { "type": "git", - "url": "git@gitlab.com:stella-maris/clock.git", + "url": "https://github.com/stella-maris-solutions/clock.git", "reference": "a94228dac03c9a8411198ce8c8dacbbe99c930c3" }, "dist": { "type": "zip", - "url": "https://gitlab.com/api/v4/projects/stella-maris%2Fclock/repository/archive.zip?sha=a94228dac03c9a8411198ce8c8dacbbe99c930c3", + "url": "https://api.github.com/repos/stella-maris-solutions/clock/zipball/a94228dac03c9a8411198ce8c8dacbbe99c930c3", "reference": "a94228dac03c9a8411198ce8c8dacbbe99c930c3", "shasum": "" }, @@ -2005,6 +2005,10 @@ "point in time", "psr20" ], + "support": { + "issues": "https://github.com/stella-maris-solutions/clock/issues", + "source": "https://github.com/stella-maris-solutions/clock/tree/0.1.6" + }, "time": "2022-09-27T15:03:11+00:00" }, { @@ -2134,6 +2138,344 @@ } ], "packages-dev": [ + { + "name": "doctrine/cache", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", + "shasum": "" + }, + "require": { + "php": "~7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "keywords": [ + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" + ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], + "time": "2022-05-20T20:07:39+00:00" + }, + { + "name": "doctrine/dbal", + "version": "3.4.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/a5a58773109c0abb13e658c8ccd92aeec8d07f9e", + "reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2", + "doctrine/cache": "^1.11|^2.0", + "doctrine/deprecations": "^0.5.3|^1", + "doctrine/event-manager": "^1.0", + "php": "^7.4 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "doctrine/coding-standard": "10.0.0", + "jetbrains/phpstorm-stubs": "2022.2", + "phpstan/phpstan": "1.8.3", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "9.5.24", + "psalm/plugin-phpunit": "0.17.0", + "squizlabs/php_codesniffer": "3.7.1", + "symfony/cache": "^5.4|^6.0", + "symfony/console": "^4.4|^5.4|^6.0", + "vimeo/psalm": "4.27.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.4.5" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "time": "2022-09-23T17:48:57+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + }, + "time": "2022-05-02T15:47:09+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", + "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "~1.4.10 || ^1.5.4", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/1.1.2" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "time": "2022-07-27T22:18:11+00:00" + }, { "name": "doctrine/instantiator", "version": "1.4.1", @@ -2263,6 +2605,28 @@ ], "time": "2022-03-03T13:19:32+00:00" }, + { + "name": "nextcloud/server", + "version": "24.0.0", + "source": { + "type": "git", + "url": "https://github.com/nextcloud/server.git", + "reference": "master" + }, + "dist": { + "type": "zip", + "url": "https://github.com/nextcloud/server/archive/refs/tags/v24.0.0.zip" + }, + "type": "library", + "autoload": { + "psr-4": { + "": "lib/private/legacy", + "OC\\": "lib/private", + "OC\\Core\\": "core/", + "OCP\\": "lib/public" + } + } + }, { "name": "nikic/php-parser", "version": "v4.15.1", @@ -3867,14 +4231,14 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "pdsinterop/solid-crud": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "^8.0", + "ext-dom": "*", "ext-json": "*", + "ext-mbstring": "*", "ext-openssl": "*" }, "platform-dev": [], From c717b0f61c98b2373ab3e5c7c87f35f219a69c49 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Fri, 30 Sep 2022 17:03:30 +0200 Subject: [PATCH 91/91] add newline --- solid/lib/Controller/SolidWebsocketController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solid/lib/Controller/SolidWebsocketController.php b/solid/lib/Controller/SolidWebsocketController.php index 5b64aa39..5807794f 100644 --- a/solid/lib/Controller/SolidWebsocketController.php +++ b/solid/lib/Controller/SolidWebsocketController.php @@ -21,4 +21,4 @@ public function register(): DataResponse "source" => $pubsub . "/?type=WebSocketSubscription2021" ]); } -} \ No newline at end of file +}