Compare commits

...

1 Commits

Author SHA1 Message Date
Thomas Citharel 326e5696c9 feat: wIP
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-09-17 11:58:10 +02:00
29 changed files with 1094 additions and 2 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<name>WebDAV</name>
<summary>WebDAV endpoint</summary>
<description>WebDAV endpoint</description>
<version>1.28.0</version>
<version>1.28.1</version>
<licence>agpl</licence>
<author>owncloud.org</author>
<namespace>DAV</namespace>
@@ -71,6 +71,8 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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',
@@ -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',
+79
View File
@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\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';
}
}
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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();
}
}
+48
View File
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>.
*
*/
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');
}
}
+75
View File
@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/**
* @copyright 2023 Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DAV\Db;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\IDBConnection;
/**
* @template-extends QBMapper<PushKey>
*/
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);
}
}
+72
View File
@@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\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);
}
}
}
}
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Your name <your@email.com>
*
* @author Your name <your@email.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\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 {
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
namespace OCA\DAV\Push;
use Sabre\Xml\XmlSerializable;
/**
* @since 28.0.0
*/
interface IPushTransport extends XmlSerializable {
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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;
}
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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;
}
}
+1
View File
@@ -181,6 +181,7 @@ class Server {
}
$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());
@@ -548,6 +548,12 @@ return array(
'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 @@ return array(
'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',
+10
View File
@@ -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',
@@ -137,6 +137,8 @@ class RegistrationContext {
/** @var ServiceRegistration<IReferenceProvider>[] */
private array $referenceProviders = [];
private array $pushNotifierServices = [];
@@ -372,6 +374,10 @@ class RegistrationContext {
$class
);
}
public function registerPushNotifierProvider(string $class): void {
$this->context->registerPushNotifierProvider($this->appId, $class);
}
};
}
@@ -523,6 +529,10 @@ class RegistrationContext {
$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 @@ class RegistrationContext {
public function getPublicShareTemplateProviders(): array {
return $this->publicShareTemplateProviders;
}
/**
* @return ServiceRegistration<\OCP\Push\IProvider>[]
*/
public function getPushNotifierServices(): array {
return $this->pushNotifierServices;
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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;
}
}
+60
View File
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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);
}
}
}
+74
View File
@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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;
}
}
@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
namespace OC\Push;
use Minishlink\WebPush\MessageSentReport;
use OCP\Push\IPushNotificationSentReport;
/**
* @since 28.0.0
*/
class PushNotificationSentReport extends MessageSentReport implements IPushNotificationSentReport {}
+2
View File
@@ -1414,6 +1414,8 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias(\OCP\TextProcessing\IManager::class, \OC\TextProcessing\Manager::class);
$this->registerAlias(\OCP\Push\IManager::class, \OC\Push\Manager::class);
$this->connectDispatcher();
}
@@ -371,4 +371,14 @@ interface IRegistrationContext {
* @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;
}
+33
View File
@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
namespace OCP\Push;
/**
* @since 28.0.0
*/
interface IDeferrableProvider extends IProvider {
public function defer(): void;
public function flush(): void;
}
+32
View File
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
namespace OCP\Push;
/**
* @since 28.0.0
*/
interface IManager {
public function getPushNotifierServices(): array;
}
+36
View File
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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;
}
+38
View File
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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;
}
+35
View File
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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;
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023, Thomas Citharel <nextcloud@tcit.fr>
*
* @author Thomas Citharel <nextcloud@tcit.fr>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
namespace OCP\Push;
/**
* @since 28.0.0
*/
interface IPushNotificationSentReport {
public function isSuccess(): bool;
public function getReason(): string;
public function getResponseContent(): ?string;
}