1
0
Fork 0

app init; implemented service detection

This commit is contained in:
Jonathan Treffler 2024-04-05 20:26:15 +02:00
parent a84bd86c63
commit b992cde357
10 changed files with 322 additions and 0 deletions

38
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,38 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch built-in server and debug",
"type": "php",
"request": "launch",
"runtimeArgs": [
"-S",
"localhost:8000",
"-t",
"."
],
"port": 9003,
"serverReadyAction": {
"action": "openExternally"
}
},
{
"name": "Debug current script in console",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"externalConsole": false,
"port": 9003
},
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003
}
]
}

18
appinfo/info.xml Normal file
View file

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>dav_push</id>
<name>DAV Push</name>
<summary>Implements the DAV Push specification</summary>
<description><![CDATA[This app allows you to send push notifications from your Nextcloud server to different clients, including mobile devices, desktop computers, and web browsers.]]></description>
<version>0.0.1</version>
<licence>agpl</licence>
<author mail="info@bitfire.at" homepage="https://github.com/bitfireAT/webdav-push">bitfire web engineering</author>
<author mail="mail@jonathan-treffler.de">Jonathan Treffler</author>
<namespace>DavPush</namespace>
<category>tools</category>
<bugs>https://github.com/bitfireAT/nc-ext-caldav-carddav-push/issues</bugs>
<dependencies>
<nextcloud min-version="28" max-version="28"/>
</dependencies>
</info>

11
appinfo/routes.php Normal file
View file

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
// SPDX-FileCopyrightText: bitfire web engineering GmbH <info@bitfire.at>
// SPDX-License-Identifier: AGPL-3.0-or-later
return [
'resources' => [
],
'routes' => [
]
];

View file

@ -0,0 +1,30 @@
<?php
// SPDX-FileCopyrightText: bitfire web engineering GmbH <info@bitfire.at>
// SPDX-License-Identifier: AGPL-3.0-or-later
namespace OCA\DavPush\AppInfo;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCA\DAV\Events\SabrePluginAddEvent;
use OCA\DavPush\Listener\SabrePluginAddListener;
class Application extends App implements IBootstrap {
public const APP_ID = 'dav_push';
public function __construct() {
parent::__construct(self::APP_ID);
}
public function register(IRegistrationContext $context): void {
$context->registerEventListener(SabrePluginAddEvent::class, SabrePluginAddListener::class);
}
public function boot(IBootContext $context): void {
}
}

View file

@ -0,0 +1,106 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.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\DavPush\Dav;
use OCP\IUser;
use OCP\IUserSession;
use OCP\AppFramework\Db\DoesNotExistException;
use OCA\DAV\Connector\Sabre\Node;
use OCA\DavPush\Transport\TransportManager;
use Sabre\DAV\INode;
use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
class ServiceDetectionPlugin extends ServerPlugin {
public const PUSH_PREFIX = '{DAV:Push}';
public const PROPERTY_PUSH_TRANSPORTS = self::PUSH_PREFIX . 'push-transports';
public const PROPERTY_PUSH_TOPIC = self::PUSH_PREFIX . 'topic';
public function __construct(
private IUserSession $userSession,
private TransportManager $transportManager,
) {
}
public function initialize(Server $server): void {
$server->on('propFind', [$this, 'propFind']);
}
public function propFind(PropFind $propFind, INode $node) {
if (count(array_intersect([self::PROPERTY_PUSH_TRANSPORTS, self::PROPERTY_PUSH_TOPIC], $propFind->getRequestedProperties())) == 0) {
return;
}
//if (!($node instanceof Node)) {
// return;
//}
$propFind->handle(
self::PROPERTY_PUSH_TRANSPORTS,
function () use ($node) {
//$user = $this->userSession->getUser();
//if (!($user instanceof IUser)) {
// return [];
//}
$transports = $this->transportManager->getTransports();
$result = [];
foreach($transports as $transport) {
$result[] = [
(self::PUSH_PREFIX . "transport") => [
(self::PUSH_PREFIX . $transport->getId()) => $transport->getAdditionalInformation(),
]
];
}
//throw new \Exception( "\$result = " . json_encode($result) );
return $result;
},
);
$propFind->handle(
self::PROPERTY_PUSH_TOPIC,
//function () use ($node) {
//$user = $this->userSession->getUser();
//if (!($user instanceof IUser)) {
// return [];
//}
// return "test-return-push";
//},
"test-return-push-topic"
);
}
}

View file

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace OCA\DavPush\Event;
use OCP\EventDispatcher\Event;
use OCA\DavPush\Transport\TransportManager;
/**
* This event is triggered during the initialization of DAV Push.
* Use it to register external push transports.
*/
class RegisterTransportsEvent extends Event {
/** @var TransportManager */
private $transportManager;
public function __construct(TransportManager $transportManager) {
parent::__construct();
$this->transportManager = $transportManager;
}
public function getTransportManager(): TransportManager {
return $this->transportManager;
}
}

View file

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace OCA\DavPush\Listener;
use OCA\DAV\Events\SabrePluginAddEvent;
use OCA\DavPush\Dav\ServiceDetectionPlugin;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use Psr\Container\ContainerInterface;
class SabrePluginAddListener implements IEventListener {
public function __construct(private ContainerInterface $container) {}
public function handle(Event $event): void {
if ($event instanceof SabrePluginAddEvent) {
$serviceDetectionPlugin = $this->container->get(ServiceDetectionPlugin::class);
$event->getServer()->addPlugin($serviceDetectionPlugin);
}
}
}

View file

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace OCA\DavPush\PushTransports;
use OCA\DavPush\Transport\Transport;
class WebPushTransport extends Transport {
protected $id = "web-push";
}

View file

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace OCA\DavPush\Transport;
abstract class Transport {
protected $id;
public function getId() {
return $this->id;
}
public function getAdditionalInformation() {
return [];
}
}

View file

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace OCA\DavPush\Transport;
use OCP\EventDispatcher\IEventDispatcher;
use OCA\DavPush\Event\RegisterTransportsEvent;
use OCA\DavPush\PushTransports\WebPushTransport;
class TransportManager {
/**
* @var Transport[]
*/
private array $transports = [];
public function __construct(IEventDispatcher $dispatcher) {
// register integrated transports
$this->registerTransport(new WebPushTransport());
// register transports provided by other apps
$event = new RegisterTransportsEvent($this);
$dispatcher->dispatchTyped($event);
}
/**
* @return Transport[]
*/
public function getTransports(): array {
return $this->transports;
}
public function registerTransport(Transport $transport): self {
$this->transports[] = $transport;
return $this;
}
}