diff --git a/3rdparty b/3rdparty
index 7293b4ffe86c0..519ea16619b9a 160000
--- a/3rdparty
+++ b/3rdparty
@@ -1 +1 @@
-Subproject commit 7293b4ffe86c0b48c3172bd8f180a12e0907fd60
+Subproject commit 519ea16619b9a6144250bb0f65542b61bead8cfa
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index bc3e73aa7186a..2c398223870e2 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -5,7 +5,7 @@
WebDAV
WebDAV endpoint
WebDAV endpoint
- 1.28.0
+ 1.28.1
agpl
owncloud.org
DAV
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 6d41801728b58..f84aa94199c20 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -71,6 +71,8 @@
'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => $baseDir . '/../lib/CalDAV/PublicCalendarRoot.php',
'OCA\\DAV\\CalDAV\\Publishing\\PublishPlugin' => $baseDir . '/../lib/CalDAV/Publishing/PublishPlugin.php',
'OCA\\DAV\\CalDAV\\Publishing\\Xml\\Publisher' => $baseDir . '/../lib/CalDAV/Publishing/Xml/Publisher.php',
+ 'OCA\\DAV\\CalDAV\\PushSync\\Plugin' => $baseDir . '/../lib/CalDAV/PushSync/Plugin.php',
+ 'OCA\\DAV\\CalDAV\\PushSync\\Xml\\PushTransports' => $baseDir . '/../lib/CalDAV/PushSync/Xml/PushTransports.php',
'OCA\\DAV\\CalDAV\\Reminder\\Backend' => $baseDir . '/../lib/CalDAV/Reminder/Backend.php',
'OCA\\DAV\\CalDAV\\Reminder\\INotificationProvider' => $baseDir . '/../lib/CalDAV/Reminder/INotificationProvider.php',
'OCA\\DAV\\CalDAV\\Reminder\\NotificationProviderManager' => $baseDir . '/../lib/CalDAV/Reminder/NotificationProviderManager.php',
@@ -203,6 +205,8 @@
'OCA\\DAV\\DAV\\ViewOnlyPlugin' => $baseDir . '/../lib/DAV/ViewOnlyPlugin.php',
'OCA\\DAV\\Db\\Direct' => $baseDir . '/../lib/Db/Direct.php',
'OCA\\DAV\\Db\\DirectMapper' => $baseDir . '/../lib/Db/DirectMapper.php',
+ 'OCA\\DAV\\Db\\PushKey' => $baseDir . '/../lib/Db/PushKey.php',
+ 'OCA\\DAV\\Db\\PushKeyMapper' => $baseDir . '/../lib/Db/PushKeyMapper.php',
'OCA\\DAV\\Direct\\DirectFile' => $baseDir . '/../lib/Direct/DirectFile.php',
'OCA\\DAV\\Direct\\DirectHome' => $baseDir . '/../lib/Direct/DirectHome.php',
'OCA\\DAV\\Direct\\Server' => $baseDir . '/../lib/Direct/Server.php',
@@ -297,9 +301,13 @@
'OCA\\DAV\\Migration\\Version1018Date20210312100735' => $baseDir . '/../lib/Migration/Version1018Date20210312100735.php',
'OCA\\DAV\\Migration\\Version1024Date20211221144219' => $baseDir . '/../lib/Migration/Version1024Date20211221144219.php',
'OCA\\DAV\\Migration\\Version1027Date20230504122946' => $baseDir . '/../lib/Migration/Version1027Date20230504122946.php',
+ 'OCA\\DAV\\Migration\\Version1028Date20230521143154' => $baseDir . '/../lib/Migration/Version1028Date20230521143154.php',
'OCA\\DAV\\Profiler\\ProfilerPlugin' => $baseDir . '/../lib/Profiler/ProfilerPlugin.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
+ 'OCA\\DAV\\Push\\IPushTransport' => $baseDir . '/../lib/Push/IPushTransport.php',
+ 'OCA\\DAV\\Push\\IPushTransportProvider' => $baseDir . '/../lib/Push/IPushTransportProvider.php',
+ 'OCA\\DAV\\Push\\PushTransportManager' => $baseDir . '/../lib/Push/PushTransportManager.php',
'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
'OCA\\DAV\\Search\\ACalendarSearchProvider' => $baseDir . '/../lib/Search/ACalendarSearchProvider.php',
'OCA\\DAV\\Search\\ContactsSearchProvider' => $baseDir . '/../lib/Search/ContactsSearchProvider.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index 600397c371e1a..37efae3e20d99 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -86,6 +86,8 @@ class ComposerStaticInitDAV
'OCA\\DAV\\CalDAV\\PublicCalendarRoot' => __DIR__ . '/..' . '/../lib/CalDAV/PublicCalendarRoot.php',
'OCA\\DAV\\CalDAV\\Publishing\\PublishPlugin' => __DIR__ . '/..' . '/../lib/CalDAV/Publishing/PublishPlugin.php',
'OCA\\DAV\\CalDAV\\Publishing\\Xml\\Publisher' => __DIR__ . '/..' . '/../lib/CalDAV/Publishing/Xml/Publisher.php',
+ 'OCA\\DAV\\CalDAV\\PushSync\\Plugin' => __DIR__ . '/..' . '/../lib/CalDAV/PushSync/Plugin.php',
+ 'OCA\\DAV\\CalDAV\\PushSync\\Xml\\PushTransports' => __DIR__ . '/..' . '/../lib/CalDAV/PushSync/Xml/PushTransports.php',
'OCA\\DAV\\CalDAV\\Reminder\\Backend' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/Backend.php',
'OCA\\DAV\\CalDAV\\Reminder\\INotificationProvider' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/INotificationProvider.php',
'OCA\\DAV\\CalDAV\\Reminder\\NotificationProviderManager' => __DIR__ . '/..' . '/../lib/CalDAV/Reminder/NotificationProviderManager.php',
@@ -218,6 +220,8 @@ class ComposerStaticInitDAV
'OCA\\DAV\\DAV\\ViewOnlyPlugin' => __DIR__ . '/..' . '/../lib/DAV/ViewOnlyPlugin.php',
'OCA\\DAV\\Db\\Direct' => __DIR__ . '/..' . '/../lib/Db/Direct.php',
'OCA\\DAV\\Db\\DirectMapper' => __DIR__ . '/..' . '/../lib/Db/DirectMapper.php',
+ 'OCA\\DAV\\Db\\PushKey' => __DIR__ . '/..' . '/../lib/Db/PushKey.php',
+ 'OCA\\DAV\\Db\\PushKeyMapper' => __DIR__ . '/..' . '/../lib/Db/PushKeyMapper.php',
'OCA\\DAV\\Direct\\DirectFile' => __DIR__ . '/..' . '/../lib/Direct/DirectFile.php',
'OCA\\DAV\\Direct\\DirectHome' => __DIR__ . '/..' . '/../lib/Direct/DirectHome.php',
'OCA\\DAV\\Direct\\Server' => __DIR__ . '/..' . '/../lib/Direct/Server.php',
@@ -312,9 +316,13 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\Version1018Date20210312100735' => __DIR__ . '/..' . '/../lib/Migration/Version1018Date20210312100735.php',
'OCA\\DAV\\Migration\\Version1024Date20211221144219' => __DIR__ . '/..' . '/../lib/Migration/Version1024Date20211221144219.php',
'OCA\\DAV\\Migration\\Version1027Date20230504122946' => __DIR__ . '/..' . '/../lib/Migration/Version1027Date20230504122946.php',
+ 'OCA\\DAV\\Migration\\Version1028Date20230521143154' => __DIR__ . '/..' . '/../lib/Migration/Version1028Date20230521143154.php',
'OCA\\DAV\\Profiler\\ProfilerPlugin' => __DIR__ . '/..' . '/../lib/Profiler/ProfilerPlugin.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningNode.php',
'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php',
+ 'OCA\\DAV\\Push\\IPushTransport' => __DIR__ . '/..' . '/../lib/Push/IPushTransport.php',
+ 'OCA\\DAV\\Push\\IPushTransportProvider' => __DIR__ . '/..' . '/../lib/Push/IPushTransportProvider.php',
+ 'OCA\\DAV\\Push\\PushTransportManager' => __DIR__ . '/..' . '/../lib/Push/PushTransportManager.php',
'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
'OCA\\DAV\\Search\\ACalendarSearchProvider' => __DIR__ . '/..' . '/../lib/Search/ACalendarSearchProvider.php',
'OCA\\DAV\\Search\\ContactsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/ContactsSearchProvider.php',
diff --git a/apps/dav/lib/CalDAV/PushSync/Plugin.php b/apps/dav/lib/CalDAV/PushSync/Plugin.php
new file mode 100644
index 0000000000000..dcc7b934805e0
--- /dev/null
+++ b/apps/dav/lib/CalDAV/PushSync/Plugin.php
@@ -0,0 +1,79 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+namespace OCA\DAV\CalDAV\PushSync;
+
+use Closure;
+use OCA\DAV\CalDAV\Calendar;
+use OCA\DAV\CalDAV\CalendarHome;
+use OCA\DAV\CalDAV\PushSync\Xml\PushTransports;
+use OCA\DAV\Db\PushKeyMapper;
+use OCA\DAV\Push\IPushTransportProvider;
+use OCA\DAV\Push\PushTransportManager;
+use Sabre\DAV\INode;
+use Sabre\DAV\PropFind;
+use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
+
+class Plugin extends ServerPlugin {
+ public const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
+ public const PROPERTY_PUSH_TRANSPORTS = '{' . self::NS_CALENDARSERVER . '}push-transports';
+ public const PROPERTY_PUSHKEY = '{' . self::NS_CALENDARSERVER . '}pushkey';
+
+ public function __construct(private PushKeyMapper $pushKeyMapper, private PushTransportManager $pushTransportManager) { }
+
+ public function initialize(Server $server): void {
+ $server->on('propFind', Closure::fromCallable([$this, 'propFind']));
+ }
+
+ private function propFind(
+ PropFind $propFind,
+ INode $node): void {
+ if ($node instanceof CalendarHome) {
+ $pushTransportProviders = $this->pushTransportManager->getPushTransportProviders();
+ $propFind->handle(self::PROPERTY_PUSH_TRANSPORTS, function () use ($node, $pushTransportProviders) {
+ return new PushTransports(array_map(function (IPushTransportProvider $pushTransportProvider) {
+ return $pushTransportProvider->getPushTransport();
+ }, $pushTransportProviders));
+ });
+ $propFind->handle(self::PROPERTY_PUSHKEY, function () use ($node) {
+ return $this->pushKeyMapper->getForPrincipal($node->getOwner());
+ });
+ }
+ if ($node instanceof Calendar) {
+ $propFind->handle(self::PROPERTY_PUSHKEY, function () use ($node) {
+ return $this->pushKeyMapper->getForUri($node->getOwner(), $node->getName());
+ });
+ }
+ }
+
+ public function getFeatures(): array {
+ return ['nc-calendar-push-sync'];
+ }
+
+ public function getPluginName(): string {
+ return 'nc-calendar-push-sync';
+ }
+}
diff --git a/apps/dav/lib/CalDAV/PushSync/Xml/PushTransports.php b/apps/dav/lib/CalDAV/PushSync/Xml/PushTransports.php
new file mode 100644
index 0000000000000..7b1525f38720d
--- /dev/null
+++ b/apps/dav/lib/CalDAV/PushSync/Xml/PushTransports.php
@@ -0,0 +1,90 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+namespace OCA\DAV\CalDAV\PushSync\Xml;
+
+use OCA\DAV\CalDAV\PushSync\Plugin;
+use OCA\DAV\Push\IPushTransport;
+use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
+
+
+class PushTransports implements XmlSerializable {
+
+ /** @var IPushTransport[] */
+ private array $pushTransports;
+
+ public function __construct(array $pushTransports) {
+ $this->pushTransports = $pushTransports;
+ }
+
+ public function getValue(): array {
+ return $this->pushTransports;
+ }
+
+ /**
+ * The xmlSerialize method is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ public function xmlSerialize(Writer $writer): void {
+ // $cs = '{' . Plugin::NS_CALENDARSERVER . '}';
+
+ if (count($this->pushTransports) <= 0) return;
+
+ //$writer->startElement($cs . 'push-transports');
+
+ foreach ($this->pushTransports as $pushTransport) {
+ $pushTransport->xmlSerialize($writer);
+
+// $writer->startElement($cs . 'transport');
+// $writer->writeAttribute('type', 'whatever');
+//
+// $writer->startElement($cs . 'subscription-url');
+// $writer->writeElement('{DAV:}href', $pushTransport->getSubscriptionUrl());
+// $writer->endElement();
+//
+// $writer->writeElement('apsbundleid', 'whatever');
+// $writer->writeElement('env', 'whatever');
+// $writer->writeElement('refresh-interval', $pushTransport->getRefreshInterval());
+//
+// $writer->endElement(); // transport
+ }
+ // $writer->endElement();
+ }
+}
diff --git a/apps/dav/lib/Db/PushKey.php b/apps/dav/lib/Db/PushKey.php
new file mode 100644
index 0000000000000..a5f3cda22ad14
--- /dev/null
+++ b/apps/dav/lib/Db/PushKey.php
@@ -0,0 +1,48 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+namespace OCA\DAV\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method string getPrincipalUri()
+ * @method void setPrincipalUri(string $principalUri)
+ * @method string getUri()
+ * @method void setUri(string $principalUri)
+ * @method string getPushKey()
+ * @method void setPushKey(string $pushKey)
+ */
+class PushKey extends Entity {
+ protected ?string $principalUri = null;
+ protected ?string $uri = null;
+ protected ?string $pushKey = null;
+
+ public function __construct() {
+ $this->addType('principalUri', 'string');
+ $this->addType('uri', 'string');
+ $this->addType('pushKey', 'string');
+ }
+}
diff --git a/apps/dav/lib/Db/PushKeyMapper.php b/apps/dav/lib/Db/PushKeyMapper.php
new file mode 100644
index 0000000000000..f18c1b0a8a662
--- /dev/null
+++ b/apps/dav/lib/Db/PushKeyMapper.php
@@ -0,0 +1,75 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+namespace OCA\DAV\Db;
+
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\IDBConnection;
+
+/**
+ * @template-extends QBMapper
+ */
+class PushKeyMapper extends QBMapper {
+ public function __construct(IDBConnection $db) {
+ parent::__construct($db, 'push_transports', PushKey::class);
+ }
+
+ /**
+ * @return PushKey[]
+ * @throws DoesNotExistException
+ */
+ public function getForPrincipal(string $principalUri): array {
+ $qb = $this->db->getQueryBuilder();
+
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where(
+ $qb->expr()->eq('principalUri', $qb->createNamedParameter($principalUri))
+ )
+ ->andWhere($qb->expr()->eq('uri', $qb->createNamedParameter(null)))
+ ;
+
+ return parent::findEntities($qb);
+ }
+
+ /**
+ * @return PushKey[]
+ * @throws DoesNotExistException
+ */
+ public function getForUri(string $principalUri, string $uri): array {
+ $qb = $this->db->getQueryBuilder();
+
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where(
+ $qb->expr()->eq('principalUri', $qb->createNamedParameter($principalUri))
+ )
+ ->andWhere($qb->expr()->eq('uri', $qb->createNamedParameter($uri)))
+ ;
+
+ return parent::findEntities($qb);
+ }
+}
diff --git a/apps/dav/lib/Listener/PushListener.php b/apps/dav/lib/Listener/PushListener.php
new file mode 100644
index 0000000000000..7fb940d113afa
--- /dev/null
+++ b/apps/dav/lib/Listener/PushListener.php
@@ -0,0 +1,72 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+namespace OCA\DAV\Listener;
+
+use OCA\DAV\Db\PushKeyMapper;
+use OCA\DAV\Events\CalendarObjectCreatedEvent;
+use OCA\DAV\Events\CalendarObjectUpdatedEvent;
+use OCA\DAV\Events\CardCreatedEvent;
+use OCA\DAV\Events\CardDeletedEvent;
+use OCA\DAV\Events\CardUpdatedEvent;
+use OCA\DAV\Push\PushTransportManager;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+
+class PushListener implements IEventListener {
+
+ public function __construct(private PushTransportManager $pushTransportManager, private PushKeyMapper $pushKeyMapper) {
+ }
+
+ public function handle(Event $event): void {
+ if ($event instanceof CalendarObjectCreatedEvent || $event instanceof CalendarObjectUpdatedEvent) {
+ $data = $event->getCalendarData();
+ $this->notify($data['uri'], $data['principaluri']);
+
+ } elseif ($event instanceof CardCreatedEvent || $event instanceof CardUpdatedEvent || $event instanceof CardDeletedEvent) {
+ $data = $event->getAddressBookData();
+ $this->notify($data['uri'], $data['principaluri']);
+ }
+ }
+
+ /**
+ * @return string[]
+ */
+ private function pushKeysForData(string $principalUri, string $uri): array {
+ $pushKeys = [];
+ $pushKeys[] = $this->pushKeyMapper->getForPrincipal($principalUri);
+ $pushKeys[] = $this->pushKeyMapper->getForUri($principalUri, $uri);
+ return $pushKeys;
+ }
+
+ private function notify(string $principalUri, string $uri): array {
+ $pushKeys = $this->pushKeysForData($principalUri, $uri);
+ foreach ($pushKeys as $pushKey) {
+ foreach ($this->pushTransportManager->getPushTransportProviders() as $pushTransportProvider) {
+ $pushTransportProvider->davNotify($pushKey);
+ }
+ }
+ }
+}
diff --git a/apps/dav/lib/Migration/Version1028Date20230521143154.php b/apps/dav/lib/Migration/Version1028Date20230521143154.php
new file mode 100644
index 0000000000000..7cb61d715613c
--- /dev/null
+++ b/apps/dav/lib/Migration/Version1028Date20230521143154.php
@@ -0,0 +1,90 @@
+
+ *
+ * @author Your name
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+namespace OCA\DAV\Migration;
+
+use Closure;
+use OCP\DB\ISchemaWrapper;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+/**
+ * Auto-generated migration step: Please modify to your needs!
+ */
+class Version1028Date20230521143154 extends SimpleMigrationStep {
+
+ /**
+ * @param IOutput $output
+ * @param Closure(): ISchemaWrapper $schemaClosure
+ * @param array $options
+ */
+ public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
+ }
+
+ /**
+ * @param IOutput $output
+ * @param Closure(): ISchemaWrapper $schemaClosure
+ * @param array $options
+ * @return null|ISchemaWrapper
+ */
+ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ if (!$schema->hasTable('dav_pushkeys')) {
+ $table = $schema->createTable('dav_pushkeys');
+ $table->addColumn('id', 'integer', [
+ 'autoincrement' => true,
+ 'notnull' => true,
+ ]);
+ $table->addColumn('principalUri', 'string', [
+ 'notnull' => true,
+ 'length' => 200
+ ]);
+ $table->addColumn('uri', 'string', [
+ 'notnull' => false,
+ 'length' => 200
+ ]);
+ $table->addColumn('pushKey', 'string', [
+ 'notnull' => true,
+ 'length' => 200
+ ]);
+
+ $table->setPrimaryKey(['id']);
+ $table->addUniqueIndex(['principalUri']);
+ $table->addUniqueIndex(['principalUri', 'uri']);
+ }
+ return $schema;
+ }
+
+ /**
+ * @param IOutput $output
+ * @param Closure(): ISchemaWrapper $schemaClosure
+ * @param array $options
+ */
+ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
+ }
+}
diff --git a/apps/dav/lib/Push/IPushTransport.php b/apps/dav/lib/Push/IPushTransport.php
new file mode 100644
index 0000000000000..d21372c65356f
--- /dev/null
+++ b/apps/dav/lib/Push/IPushTransport.php
@@ -0,0 +1,34 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\DAV\Push;
+
+use Sabre\Xml\XmlSerializable;
+
+/**
+ * @since 28.0.0
+ */
+interface IPushTransport extends XmlSerializable {
+
+}
diff --git a/apps/dav/lib/Push/IPushTransportProvider.php b/apps/dav/lib/Push/IPushTransportProvider.php
new file mode 100644
index 0000000000000..a47c257e78d6e
--- /dev/null
+++ b/apps/dav/lib/Push/IPushTransportProvider.php
@@ -0,0 +1,37 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\DAV\Push;
+
+
+use OCP\Push\IProvider;
+
+/**
+ * @since 28.0.0
+ */
+interface IPushTransportProvider extends IProvider {
+
+ public function davNotify(string $pushKey): void;
+ public function getPushTransport(): IPushTransport;
+}
diff --git a/apps/dav/lib/Push/PushTransportManager.php b/apps/dav/lib/Push/PushTransportManager.php
new file mode 100644
index 0000000000000..64c06d7b2b052
--- /dev/null
+++ b/apps/dav/lib/Push/PushTransportManager.php
@@ -0,0 +1,50 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCA\DAV\Push;
+
+
+use OCP\Push\IManager;
+
+/**
+ * @since 28.0.0
+ */
+class PushTransportManager {
+ private array $pushTransportProviders = [];
+
+ public function __construct(IManager $pushManager) {
+ $this->pushTransportProviders = array_filter($pushManager->getPushNotifierServices(), function ($pushNotifierService) {
+ return $pushNotifierService instanceof IPushTransportProvider;
+ });
+ }
+
+ /**
+ * @return IPushTransportProvider[]
+ */
+ public function getPushTransportProviders(): array
+ {
+ return $this->pushTransportProviders;
+ }
+
+}
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index 603e015fca952..03c1f332fa01f 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -181,6 +181,7 @@ public function __construct(IRequest $request, string $baseUri) {
}
$this->server->addPlugin(\OC::$server->get(\OCA\DAV\CalDAV\Trashbin\Plugin::class));
+ $this->server->addPlugin(\OC::$server->get(\OCA\DAV\CalDAV\PushSync\Plugin::class));
$this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($request));
if (\OC::$server->getConfig()->getAppValue('dav', 'allow_calendar_link_subscriptions', 'yes') === 'yes') {
$this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index fb063a8208821..803a04bfc6d0c 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -548,6 +548,12 @@
'OCP\\Profile\\ParameterDoesNotExistException' => $baseDir . '/lib/public/Profile/ParameterDoesNotExistException.php',
'OCP\\Profiler\\IProfile' => $baseDir . '/lib/public/Profiler/IProfile.php',
'OCP\\Profiler\\IProfiler' => $baseDir . '/lib/public/Profiler/IProfiler.php',
+ 'OCP\\Push\\IDeferrableProvider' => $baseDir . '/lib/public/Push/IDeferrableProvider.php',
+ 'OCP\\Push\\IManager' => $baseDir . '/lib/public/Push/IManager.php',
+ 'OCP\\Push\\IProvider' => $baseDir . '/lib/public/Push/IProvider.php',
+ 'OCP\\Push\\IPush' => $baseDir . '/lib/public/Push/IPush.php',
+ 'OCP\\Push\\IPushNotification' => $baseDir . '/lib/public/Push/IPushNotification.php',
+ 'OCP\\Push\\IPushNotificationSentReport' => $baseDir . '/lib/public/Push/IPushNotificationSentReport.php',
'OCP\\Remote\\Api\\IApiCollection' => $baseDir . '/lib/public/Remote/Api/IApiCollection.php',
'OCP\\Remote\\Api\\IApiFactory' => $baseDir . '/lib/public/Remote/Api/IApiFactory.php',
'OCP\\Remote\\Api\\ICapabilitiesApi' => $baseDir . '/lib/public/Remote/Api/ICapabilitiesApi.php',
@@ -1523,6 +1529,10 @@
'OC\\Profiler\\Profile' => $baseDir . '/lib/private/Profiler/Profile.php',
'OC\\Profiler\\Profiler' => $baseDir . '/lib/private/Profiler/Profiler.php',
'OC\\Profiler\\RoutingDataCollector' => $baseDir . '/lib/private/Profiler/RoutingDataCollector.php',
+ 'OC\\Push\\Manager' => $baseDir . '/lib/private/Push/Manager.php',
+ 'OC\\Push\\Push' => $baseDir . '/lib/private/Push/Push.php',
+ 'OC\\Push\\PushNotification' => $baseDir . '/lib/private/Push/PushNotification.php',
+ 'OC\\Push\\PushNotificationSentReport' => $baseDir . '/lib/private/Push/PushNotificationSentReport.php',
'OC\\RedisFactory' => $baseDir . '/lib/private/RedisFactory.php',
'OC\\Remote\\Api\\ApiBase' => $baseDir . '/lib/private/Remote/Api/ApiBase.php',
'OC\\Remote\\Api\\ApiCollection' => $baseDir . '/lib/private/Remote/Api/ApiCollection.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 35b2318c4b166..95e17a447b94b 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -581,6 +581,12 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Profile\\ParameterDoesNotExistException' => __DIR__ . '/../../..' . '/lib/public/Profile/ParameterDoesNotExistException.php',
'OCP\\Profiler\\IProfile' => __DIR__ . '/../../..' . '/lib/public/Profiler/IProfile.php',
'OCP\\Profiler\\IProfiler' => __DIR__ . '/../../..' . '/lib/public/Profiler/IProfiler.php',
+ 'OCP\\Push\\IDeferrableProvider' => __DIR__ . '/../../..' . '/lib/public/Push/IDeferrableProvider.php',
+ 'OCP\\Push\\IManager' => __DIR__ . '/../../..' . '/lib/public/Push/IManager.php',
+ 'OCP\\Push\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Push/IProvider.php',
+ 'OCP\\Push\\IPush' => __DIR__ . '/../../..' . '/lib/public/Push/IPush.php',
+ 'OCP\\Push\\IPushNotification' => __DIR__ . '/../../..' . '/lib/public/Push/IPushNotification.php',
+ 'OCP\\Push\\IPushNotificationSentReport' => __DIR__ . '/../../..' . '/lib/public/Push/IPushNotificationSentReport.php',
'OCP\\Remote\\Api\\IApiCollection' => __DIR__ . '/../../..' . '/lib/public/Remote/Api/IApiCollection.php',
'OCP\\Remote\\Api\\IApiFactory' => __DIR__ . '/../../..' . '/lib/public/Remote/Api/IApiFactory.php',
'OCP\\Remote\\Api\\ICapabilitiesApi' => __DIR__ . '/../../..' . '/lib/public/Remote/Api/ICapabilitiesApi.php',
@@ -1556,6 +1562,10 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Profiler\\Profile' => __DIR__ . '/../../..' . '/lib/private/Profiler/Profile.php',
'OC\\Profiler\\Profiler' => __DIR__ . '/../../..' . '/lib/private/Profiler/Profiler.php',
'OC\\Profiler\\RoutingDataCollector' => __DIR__ . '/../../..' . '/lib/private/Profiler/RoutingDataCollector.php',
+ 'OC\\Push\\Manager' => __DIR__ . '/../../..' . '/lib/private/Push/Manager.php',
+ 'OC\\Push\\Push' => __DIR__ . '/../../..' . '/lib/private/Push/Push.php',
+ 'OC\\Push\\PushNotification' => __DIR__ . '/../../..' . '/lib/private/Push/PushNotification.php',
+ 'OC\\Push\\PushNotificationSentReport' => __DIR__ . '/../../..' . '/lib/private/Push/PushNotificationSentReport.php',
'OC\\RedisFactory' => __DIR__ . '/../../..' . '/lib/private/RedisFactory.php',
'OC\\Remote\\Api\\ApiBase' => __DIR__ . '/../../..' . '/lib/private/Remote/Api/ApiBase.php',
'OC\\Remote\\Api\\ApiCollection' => __DIR__ . '/../../..' . '/lib/private/Remote/Api/ApiCollection.php',
diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
index 5aea2a7a744b0..1fc9dd740994c 100644
--- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php
+++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
@@ -137,6 +137,8 @@ class RegistrationContext {
/** @var ServiceRegistration[] */
private array $referenceProviders = [];
+ private array $pushNotifierServices = [];
+
@@ -372,6 +374,10 @@ public function registerPublicShareTemplateProvider(string $class): void {
$class
);
}
+
+ public function registerPushNotifierProvider(string $class): void {
+ $this->context->registerPushNotifierProvider($this->appId, $class);
+ }
};
}
@@ -523,6 +529,10 @@ public function registerPublicShareTemplateProvider(string $appId, string $class
$this->publicShareTemplateProviders[] = new ServiceRegistration($appId, $class);
}
+ public function registerPushNotifierProvider(string $appId, string $class): void {
+ $this->pushNotifierServices[] = new ServiceRegistration($appId, $class);
+ }
+
/**
* @param App[] $apps
*/
@@ -828,4 +838,11 @@ public function getSensitiveMethods(): array {
public function getPublicShareTemplateProviders(): array {
return $this->publicShareTemplateProviders;
}
+
+ /**
+ * @return ServiceRegistration<\OCP\Push\IProvider>[]
+ */
+ public function getPushNotifierServices(): array {
+ return $this->pushNotifierServices;
+ }
}
diff --git a/lib/private/Push/Manager.php b/lib/private/Push/Manager.php
new file mode 100644
index 0000000000000..291b76edd5e7a
--- /dev/null
+++ b/lib/private/Push/Manager.php
@@ -0,0 +1,76 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OC\Push;
+
+use OC\AppFramework\Bootstrap\Coordinator;
+use OCP\Push\IManager;
+use OCP\Push\IProvider;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * @since 28.0.0
+ */
+class Manager implements IManager {
+
+ public function __construct(private LoggerInterface $logger, private Coordinator $coordinator) { }
+
+ /**
+ * @return IProvider[]
+ */
+ public function getPushNotifierServices(): array {
+ $notifierServices = [];
+
+ $notifierServiceRegistrations = $this->coordinator->getRegistrationContext()->getPushNotifierServices();
+
+ if (empty($notifierServiceRegistrations)) {
+ return $notifierServices;
+ }
+
+ foreach ($notifierServiceRegistrations as $notifierServiceRegistration) {
+ $serviceClass = $notifierServiceRegistration->getService();
+ try {
+ $notifierService = \OC::$server->get($serviceClass);
+ } catch (ContainerExceptionInterface $e) {
+ $this->logger->error('Failed to load push notification service class: ' . $serviceClass, [
+ 'exception' => $e,
+ 'app' => 'notifications',
+ ]);
+ continue;
+ }
+
+ if (!($notifierService instanceof IProvider)) {
+ $this->logger->error('Push notification notifier class ' . $serviceClass . ' is not implementing ' . IProvider::class, [
+ 'app' => 'notifications',
+ ]);
+ continue;
+ }
+
+ $notifierServices[] = $notifierService;
+ }
+
+ return $notifierServices;
+ }
+}
diff --git a/lib/private/Push/Push.php b/lib/private/Push/Push.php
new file mode 100644
index 0000000000000..b2116c0c376d1
--- /dev/null
+++ b/lib/private/Push/Push.php
@@ -0,0 +1,60 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OC\Push;
+
+use OCP\IUser;
+use OCP\Push\IProvider;
+use OCP\Push\IPush;
+use OCP\Push\IPushNotification;
+
+/**
+ * @since 28.0.0
+ */
+class Push implements IPush {
+
+ /** @var IProvider[] */
+ private array $pushNotificationServices;
+
+ public function __construct(private Manager $manager) {
+ $this->pushNotificationServices = $this->manager->getPushNotifierServices();
+ }
+
+ public function createNotification(IUser $user, string $payload): IPushNotification {
+
+ }
+
+
+ public function queueNotification(IPushNotification $pushNotification): array {
+ return array_map(function ($service) use ($pushNotification) {
+ return $service->queueNotification($pushNotification);
+ }, $this->pushNotificationServices);
+ }
+
+ public function queueNotifications(array $pushNotifications, \Closure $report): void {
+ foreach ($this->pushNotificationServices as $service) {
+ $service->queueNotifications($pushNotifications, $report);
+ }
+ }
+}
diff --git a/lib/private/Push/PushNotification.php b/lib/private/Push/PushNotification.php
new file mode 100644
index 0000000000000..1cc0e362f2454
--- /dev/null
+++ b/lib/private/Push/PushNotification.php
@@ -0,0 +1,74 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OC\Push;
+
+use OCP\Push\IPushNotification;
+
+/**
+ * @since 28.0.0
+ */
+class PushNotification implements IPushNotification {
+
+ private string $endpoint;
+ private string $publicKey;
+ private string $authToken;
+ private string $payload;
+
+ public function getEndpoint(): string {
+ return $this->endpoint;
+ }
+
+ public function setEndpoint(string $endpoint): PushNotification {
+ $this->endpoint = $endpoint;
+ return $this;
+ }
+
+ public function getPublicKey(): string {
+ return $this->publicKey;
+ }
+
+ public function setPublicKey(string $publicKey): PushNotification {
+ $this->publicKey = $publicKey;
+ return $this;
+ }
+
+ public function getAuthToken(): string {
+ return $this->authToken;
+ }
+
+ public function setAuthToken(string $authToken): PushNotification {
+ $this->authToken = $authToken;
+ return $this;
+ }
+
+ public function getPayload(): string {
+ return $this->payload;
+ }
+
+ public function setPayload(string $payload): PushNotification {
+ $this->payload = $payload;
+ return $this;
+ }
+}
diff --git a/lib/private/Push/PushNotificationSentReport.php b/lib/private/Push/PushNotificationSentReport.php
new file mode 100644
index 0000000000000..c115ee5781a9a
--- /dev/null
+++ b/lib/private/Push/PushNotificationSentReport.php
@@ -0,0 +1,33 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OC\Push;
+
+use Minishlink\WebPush\MessageSentReport;
+use OCP\Push\IPushNotificationSentReport;
+
+/**
+ * @since 28.0.0
+ */
+class PushNotificationSentReport extends MessageSentReport implements IPushNotificationSentReport {}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index ba8b18f9a05bd..329786cd3fd2d 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -1414,6 +1414,8 @@ public function __construct($webRoot, \OC\Config $config) {
$this->registerAlias(\OCP\TextProcessing\IManager::class, \OC\TextProcessing\Manager::class);
+ $this->registerAlias(\OCP\Push\IManager::class, \OC\Push\Manager::class);
+
$this->connectDispatcher();
}
diff --git a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
index 720803a78d170..7aafe1ba6b037 100644
--- a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
+++ b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
@@ -371,4 +371,14 @@ public function registerSensitiveMethods(string $class, array $methods): void;
* @since 26.0.0
*/
public function registerPublicShareTemplateProvider(string $class): void;
+
+ /**
+ * Register an implementation of Push\IProvider.
+ *
+ * @param string $class
+ * @psalm-param class-string<\OCP\Push\IProvider> $class
+ * @return void
+ * @since 28.0.0
+ */
+ public function registerPushNotifierProvider(string $class): void;
}
diff --git a/lib/public/Push/IDeferrableProvider.php b/lib/public/Push/IDeferrableProvider.php
new file mode 100644
index 0000000000000..85087f6dd7e86
--- /dev/null
+++ b/lib/public/Push/IDeferrableProvider.php
@@ -0,0 +1,33 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCP\Push;
+
+/**
+ * @since 28.0.0
+ */
+interface IDeferrableProvider extends IProvider {
+ public function defer(): void;
+ public function flush(): void;
+}
diff --git a/lib/public/Push/IManager.php b/lib/public/Push/IManager.php
new file mode 100644
index 0000000000000..91fc6c2489fa2
--- /dev/null
+++ b/lib/public/Push/IManager.php
@@ -0,0 +1,32 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCP\Push;
+
+/**
+ * @since 28.0.0
+ */
+interface IManager {
+ public function getPushNotifierServices(): array;
+}
diff --git a/lib/public/Push/IProvider.php b/lib/public/Push/IProvider.php
new file mode 100644
index 0000000000000..49bf927be1364
--- /dev/null
+++ b/lib/public/Push/IProvider.php
@@ -0,0 +1,36 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCP\Push;
+
+/**
+ * @since 28.0.0
+ */
+interface IProvider {
+ public function notify(IPushNotification $notification): void;
+
+ public function queueNotification(IPushNotification $pushNotification): IPushNotificationSentReport;
+
+ public function queueNotifications(array $pushNotifications, \Closure $report): void;
+}
diff --git a/lib/public/Push/IPush.php b/lib/public/Push/IPush.php
new file mode 100644
index 0000000000000..cfc92b8dd0770
--- /dev/null
+++ b/lib/public/Push/IPush.php
@@ -0,0 +1,38 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCP\Push;
+
+/**
+ * @since 28.0.0
+ */
+interface IPush {
+
+ /**
+ * @return IPushNotificationSentReport[]
+ */
+ public function queueNotification(IPushNotification $pushNotification): array;
+
+ public function queueNotifications(array $pushNotifications, \Closure $report): void;
+}
diff --git a/lib/public/Push/IPushNotification.php b/lib/public/Push/IPushNotification.php
new file mode 100644
index 0000000000000..792f2c6896cd6
--- /dev/null
+++ b/lib/public/Push/IPushNotification.php
@@ -0,0 +1,35 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCP\Push;
+
+/**
+ * @since 28.0.0
+ */
+interface IPushNotification {
+ public function getEndpoint(): string;
+ public function getPublicKey(): string;
+ public function getAuthToken(): string;
+ public function getPayload(): string;
+}
diff --git a/lib/public/Push/IPushNotificationSentReport.php b/lib/public/Push/IPushNotificationSentReport.php
new file mode 100644
index 0000000000000..0647999d5ca88
--- /dev/null
+++ b/lib/public/Push/IPushNotificationSentReport.php
@@ -0,0 +1,34 @@
+
+ *
+ * @author Thomas Citharel
+ *
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OCP\Push;
+
+/**
+ * @since 28.0.0
+ */
+interface IPushNotificationSentReport {
+ public function isSuccess(): bool;
+ public function getReason(): string;
+ public function getResponseContent(): ?string;
+}