diff --git a/apps/cloud_federation_api/appinfo/info.xml b/apps/cloud_federation_api/appinfo/info.xml
index f9ca8185dcf55..8de2444ff2aab 100644
--- a/apps/cloud_federation_api/appinfo/info.xml
+++ b/apps/cloud_federation_api/appinfo/info.xml
@@ -12,8 +12,8 @@
- files
- https://github.com/nextcloud/cloud_federation/issues
+ integration
+ https://github.com/nextcloud/server/issues
diff --git a/apps/cloud_federation_api/lib/Capabilities.php b/apps/cloud_federation_api/lib/Capabilities.php
index 1682effb1457c..9b04145caa231 100644
--- a/apps/cloud_federation_api/lib/Capabilities.php
+++ b/apps/cloud_federation_api/lib/Capabilities.php
@@ -28,18 +28,17 @@
namespace OCA\CloudFederationAPI;
-use OC\OCM\Model\OCMProvider;
-use OC\OCM\Model\OCMResource;
use OCP\Capabilities\ICapability;
use OCP\IURLGenerator;
use OCP\OCM\Exceptions\OCMArgumentException;
+use OCP\OCM\IOCMProvider;
class Capabilities implements ICapability {
-
public const API_VERSION = '1.0-proposal1';
public function __construct(
private IURLGenerator $urlGenerator,
+ private IOCMProvider $provider,
) {
}
@@ -63,24 +62,23 @@ public function __construct(
public function getCapabilities() {
$url = $this->urlGenerator->linkToRouteAbsolute('cloud_federation_api.requesthandlercontroller.addShare');
- $provider = new OCMProvider();
- $provider->setEnabled(true);
- $provider->setApiVersion(self::API_VERSION);
+ $this->provider->setEnabled(true);
+ $this->provider->setApiVersion(self::API_VERSION);
$pos = strrpos($url, '/');
if (false === $pos) {
throw new OCMArgumentException('generated route should contains a slash character');
}
- $provider->setEndPoint(substr($url, 0, $pos));
+ $this->provider->setEndPoint(substr($url, 0, $pos));
- $resource = new OCMResource();
+ $resource = $this->provider->createNewResourceType();
$resource->setName('file')
->setShareTypes(['user', 'group'])
->setProtocols(['webdav' => '/public.php/webdav/']);
- $provider->setResourceTypes([$resource]);
+ $this->provider->addResourceType($resource);
- return ['ocm' => $provider->jsonSerialize()];
+ return ['ocm' => $this->provider->jsonSerialize()];
}
}
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 108a2f74b5031..4387852556d96 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -537,6 +537,7 @@
'OCP\\Notification\\IManager' => $baseDir . '/lib/public/Notification/IManager.php',
'OCP\\Notification\\INotification' => $baseDir . '/lib/public/Notification/INotification.php',
'OCP\\Notification\\INotifier' => $baseDir . '/lib/public/Notification/INotifier.php',
+ 'OCP\\OCM\\Events\\ResourceTypeRegisterEvent' => $baseDir . '/lib/public/OCM/Events/ResourceTypeRegisterEvent.php',
'OCP\\OCM\\Exceptions\\OCMArgumentException' => $baseDir . '/lib/public/OCM/Exceptions/OCMArgumentException.php',
'OCP\\OCM\\Exceptions\\OCMProviderException' => $baseDir . '/lib/public/OCM/Exceptions/OCMProviderException.php',
'OCP\\OCM\\IOCMDiscoveryService' => $baseDir . '/lib/public/OCM/IOCMDiscoveryService.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index ae1f13fc89bde..9b33577d66a26 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -570,6 +570,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Notification\\IManager' => __DIR__ . '/../../..' . '/lib/public/Notification/IManager.php',
'OCP\\Notification\\INotification' => __DIR__ . '/../../..' . '/lib/public/Notification/INotification.php',
'OCP\\Notification\\INotifier' => __DIR__ . '/../../..' . '/lib/public/Notification/INotifier.php',
+ 'OCP\\OCM\\Events\\ResourceTypeRegisterEvent' => __DIR__ . '/../../..' . '/lib/public/OCM/Events/ResourceTypeRegisterEvent.php',
'OCP\\OCM\\Exceptions\\OCMArgumentException' => __DIR__ . '/../../..' . '/lib/public/OCM/Exceptions/OCMArgumentException.php',
'OCP\\OCM\\Exceptions\\OCMProviderException' => __DIR__ . '/../../..' . '/lib/public/OCM/Exceptions/OCMProviderException.php',
'OCP\\OCM\\IOCMDiscoveryService' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMDiscoveryService.php',
diff --git a/lib/private/OCM/Model/OCMProvider.php b/lib/private/OCM/Model/OCMProvider.php
index 44f4fbebc107c..084d4f8479dc2 100644
--- a/lib/private/OCM/Model/OCMProvider.php
+++ b/lib/private/OCM/Model/OCMProvider.php
@@ -26,27 +26,36 @@
namespace OC\OCM\Model;
-use JsonSerializable;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\OCM\Events\ResourceTypeRegisterEvent;
use OCP\OCM\Exceptions\OCMArgumentException;
use OCP\OCM\Exceptions\OCMProviderException;
use OCP\OCM\IOCMProvider;
+use OCP\OCM\IOCMResource;
/**
* @since 28.0.0
*/
-class OCMProvider implements IOCMProvider, JsonSerializable {
+class OCMProvider implements IOCMProvider {
private bool $enabled = false;
private string $apiVersion = '';
private string $endPoint = '';
- /** @var OCMResource[] */
+ /** @var IOCMResource[] */
private array $resourceTypes = [];
+ private bool $emittedEvent = false;
+
+ public function __construct(
+ protected IEventDispatcher $dispatcher,
+ ) {
+ }
+
/**
* @param bool $enabled
*
- * @return OCMProvider
+ * @return $this
*/
- public function setEnabled(bool $enabled): self {
+ public function setEnabled(bool $enabled): static {
$this->enabled = $enabled;
return $this;
@@ -62,9 +71,9 @@ public function isEnabled(): bool {
/**
* @param string $apiVersion
*
- * @return OCMProvider
+ * @return $this
*/
- public function setApiVersion(string $apiVersion): self {
+ public function setApiVersion(string $apiVersion): static {
$this->apiVersion = $apiVersion;
return $this;
@@ -80,9 +89,9 @@ public function getApiVersion(): string {
/**
* @param string $endPoint
*
- * @return OCMProvider
+ * @return $this
*/
- public function setEndPoint(string $endPoint): self {
+ public function setEndPoint(string $endPoint): static {
$this->endPoint = $endPoint;
return $this;
@@ -96,31 +105,45 @@ public function getEndPoint(): string {
}
/**
- * @param OCMResource $resource
+ * create a new resource to later add it with {@see IOCMProvider::addResourceType()}
+ * @return IOCMResource
+ */
+ public function createNewResourceType(): IOCMResource {
+ return new OCMResource();
+ }
+
+ /**
+ * @param IOCMResource $resource
*
* @return $this
*/
- public function addResourceType(OCMResource $resource): self {
+ public function addResourceType(IOCMResource $resource): static {
$this->resourceTypes[] = $resource;
return $this;
}
/**
- * @param OCMResource[] $resourceTypes
+ * @param IOCMResource[] $resourceTypes
*
- * @return OCMProvider
+ * @return $this
*/
- public function setResourceTypes(array $resourceTypes): self {
+ public function setResourceTypes(array $resourceTypes): static {
$this->resourceTypes = $resourceTypes;
return $this;
}
/**
- * @return OCMResource[]
+ * @return IOCMResource[]
*/
public function getResourceTypes(): array {
+ if (!$this->emittedEvent) {
+ $this->emittedEvent = true;
+ $event = new ResourceTypeRegisterEvent($this);
+ $this->dispatcher->dispatchTyped($event);
+ }
+
return $this->resourceTypes;
}
@@ -151,11 +174,11 @@ public function extractProtocolEntry(string $resourceName, string $protocol): st
*
* @param array $data
*
- * @return self
+ * @return $this
* @throws OCMProviderException in case a descent provider cannot be generated from data
* @see self::jsonSerialize()
*/
- public function import(array $data): self {
+ public function import(array $data): static {
$this->setEnabled(is_bool($data['enabled'] ?? '') ? $data['enabled'] : false)
->setApiVersion((string)($data['apiVersion'] ?? ''))
->setEndPoint($data['endPoint'] ?? '');
diff --git a/lib/private/OCM/Model/OCMResource.php b/lib/private/OCM/Model/OCMResource.php
index 12948aa8949ac..c4a91f2eabf63 100644
--- a/lib/private/OCM/Model/OCMResource.php
+++ b/lib/private/OCM/Model/OCMResource.php
@@ -26,13 +26,12 @@
namespace OC\OCM\Model;
-use JsonSerializable;
use OCP\OCM\IOCMResource;
/**
* @since 28.0.0
*/
-class OCMResource implements IOCMResource, JsonSerializable {
+class OCMResource implements IOCMResource {
private string $name = '';
/** @var string[] */
private array $shareTypes = [];
@@ -42,9 +41,9 @@ class OCMResource implements IOCMResource, JsonSerializable {
/**
* @param string $name
*
- * @return OCMResource
+ * @return $this
*/
- public function setName(string $name): self {
+ public function setName(string $name): static {
$this->name = $name;
return $this;
@@ -60,9 +59,9 @@ public function getName(): string {
/**
* @param string[] $shareTypes
*
- * @return OCMResource
+ * @return $this
*/
- public function setShareTypes(array $shareTypes): self {
+ public function setShareTypes(array $shareTypes): static {
$this->shareTypes = $shareTypes;
return $this;
@@ -80,7 +79,7 @@ public function getShareTypes(): array {
*
* @return $this
*/
- public function setProtocols(array $protocols): self {
+ public function setProtocols(array $protocols): static {
$this->protocols = $protocols;
return $this;
@@ -98,17 +97,16 @@ public function getProtocols(): array {
*
* @param array $data
*
- * @return self
+ * @return $this
* @see self::jsonSerialize()
*/
- public function import(array $data): self {
+ public function import(array $data): static {
return $this->setName((string)($data['name'] ?? ''))
->setShareTypes($data['shareTypes'] ?? [])
->setProtocols($data['protocols'] ?? []);
}
/**
- *
* @return array{
* name: string,
* shareTypes: string[],
diff --git a/lib/private/OCM/OCMDiscoveryService.php b/lib/private/OCM/OCMDiscoveryService.php
index e3b1d3508133d..ac9bf2a3965c6 100644
--- a/lib/private/OCM/OCMDiscoveryService.php
+++ b/lib/private/OCM/OCMDiscoveryService.php
@@ -27,7 +27,6 @@
namespace OC\OCM;
use JsonException;
-use OC\OCM\Model\OCMProvider;
use OCP\AppFramework\Http;
use OCP\Http\Client\IClientService;
use OCP\ICache;
@@ -54,7 +53,8 @@ public function __construct(
ICacheFactory $cacheFactory,
private IClientService $clientService,
private IConfig $config,
- private LoggerInterface $logger
+ private IOCMProvider $provider,
+ private LoggerInterface $logger,
) {
$this->cache = $cacheFactory->createDistributed('ocm-discovery');
}
@@ -69,13 +69,12 @@ public function __construct(
*/
public function discover(string $remote, bool $skipCache = false): IOCMProvider {
$remote = rtrim($remote, '/');
- $provider = new OCMProvider();
if (!$skipCache) {
try {
- $provider->import(json_decode($this->cache->get($remote) ?? '', true, 8, JSON_THROW_ON_ERROR) ?? []);
- if ($this->supportedAPIVersion($provider->getApiVersion())) {
- return $provider; // if cache looks valid, we use it
+ $this->provider->import(json_decode($this->cache->get($remote) ?? '', true, 8, JSON_THROW_ON_ERROR) ?? []);
+ if ($this->supportedAPIVersion($this->provider->getApiVersion())) {
+ return $this->provider; // if cache looks valid, we use it
}
} catch (JsonException|OCMProviderException $e) {
// we ignore cache on issues
@@ -96,7 +95,7 @@ public function discover(string $remote, bool $skipCache = false): IOCMProvider
if ($response->getStatusCode() === Http::STATUS_OK) {
$body = $response->getBody();
// update provider with data returned by the request
- $provider->import(json_decode($body, true, 8, JSON_THROW_ON_ERROR) ?? []);
+ $this->provider->import(json_decode($body, true, 8, JSON_THROW_ON_ERROR) ?? []);
$this->cache->set($remote, $body, 60 * 60 * 24);
}
} catch (JsonException|OCMProviderException $e) {
@@ -109,11 +108,11 @@ public function discover(string $remote, bool $skipCache = false): IOCMProvider
throw new OCMProviderException('error while requesting remote ocm provider');
}
- if (!$this->supportedAPIVersion($provider->getApiVersion())) {
+ if (!$this->supportedAPIVersion($this->provider->getApiVersion())) {
throw new OCMProviderException('API version not supported');
}
- return $provider;
+ return $this->provider;
}
/**
diff --git a/lib/private/Server.php b/lib/private/Server.php
index d2a1d890ccd25..949a7ccfd3f4d 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -124,6 +124,7 @@
use OC\Metadata\IMetadataManager;
use OC\Metadata\MetadataManager;
use OC\Notification\Manager;
+use OC\OCM\Model\OCMProvider;
use OC\OCM\OCMDiscoveryService;
use OC\OCS\DiscoveryService;
use OC\Preview\GeneratorHelper;
@@ -232,6 +233,7 @@
use OCP\Log\ILogFactory;
use OCP\Mail\IMailer;
use OCP\OCM\IOCMDiscoveryService;
+use OCP\OCM\IOCMProvider;
use OCP\Remote\Api\IApiFactory;
use OCP\Remote\IInstanceFactory;
use OCP\RichObjectStrings\IValidator;
@@ -1426,6 +1428,8 @@ public function __construct($webRoot, \OC\Config $config) {
$this->registerAlias(IPhoneNumberUtil::class, PhoneNumberUtil::class);
+ $this->registerAlias(IOCMProvider::class, OCMProvider::class);
+
$this->connectDispatcher();
}
diff --git a/lib/public/OCM/Events/ResourceTypeRegisterEvent.php b/lib/public/OCM/Events/ResourceTypeRegisterEvent.php
new file mode 100644
index 0000000000000..1048d8d0d493b
--- /dev/null
+++ b/lib/public/OCM/Events/ResourceTypeRegisterEvent.php
@@ -0,0 +1,62 @@
+
+ *
+ * @author Joas Schilling
+ *
+ * @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 OCP\OCM\Events;
+
+use OCP\EventDispatcher\Event;
+use OCP\OCM\IOCMProvider;
+
+/**
+ * Use this event to register additional OCM resources before the API returns
+ * them in the OCM provider list and capability
+ *
+ * @since 28.0.0
+ */
+class ResourceTypeRegisterEvent extends Event {
+ /**
+ * @param IOCMProvider $provider
+ * @since 28.0.0
+ */
+ public function __construct(
+ protected IOCMProvider $provider,
+ ) {
+ parent::__construct();
+ }
+
+ /**
+ * @param string $name
+ * @param list $shareTypes List of supported share recipients, e.g. 'user', 'group', …
+ * @param array $protocols List of supported protocols and their location,
+ * e.g. ['webdav' => '/remote.php/webdav/']
+ * @since 28.0.0
+ */
+ public function registerResourceType(string $name, array $shareTypes, array $protocols): void {
+ $resourceType = $this->provider->createNewResourceType();
+ $resourceType->setName($name)
+ ->setShareTypes($shareTypes)
+ ->setProtocols($protocols);
+ $this->provider->addResourceType($resourceType);
+ }
+}
diff --git a/lib/public/OCM/IOCMProvider.php b/lib/public/OCM/IOCMProvider.php
index f99ccf1cd238e..6df7eed370c50 100644
--- a/lib/public/OCM/IOCMProvider.php
+++ b/lib/public/OCM/IOCMProvider.php
@@ -26,7 +26,7 @@
namespace OCP\OCM;
-use OC\OCM\Model\OCMResource;
+use JsonSerializable;
use OCP\OCM\Exceptions\OCMArgumentException;
use OCP\OCM\Exceptions\OCMProviderException;
@@ -35,16 +35,16 @@
* @link https://github.com/cs3org/OCM-API/
* @since 28.0.0
*/
-interface IOCMProvider {
+interface IOCMProvider extends JsonSerializable {
/**
* enable OCM
*
* @param bool $enabled
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function setEnabled(bool $enabled): self;
+ public function setEnabled(bool $enabled): static;
/**
* is set as enabled ?
@@ -59,10 +59,10 @@ public function isEnabled(): bool;
*
* @param string $apiVersion
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function setApiVersion(string $apiVersion): self;
+ public function setApiVersion(string $apiVersion): static;
/**
* returns API version
@@ -77,10 +77,10 @@ public function getApiVersion(): string;
*
* @param string $endPoint
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function setEndPoint(string $endPoint): self;
+ public function setEndPoint(string $endPoint): static;
/**
* get configured endpoint
@@ -90,25 +90,32 @@ public function setEndPoint(string $endPoint): self;
*/
public function getEndPoint(): string;
+ /**
+ * create a new resource to later add it with {@see addResourceType()}
+ * @return IOCMResource
+ * @since 28.0.0
+ */
+ public function createNewResourceType(): IOCMResource;
+
/**
* add a single resource to the object
*
- * @param OCMResource $resource
+ * @param IOCMResource $resource
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function addResourceType(OCMResource $resource): self;
+ public function addResourceType(IOCMResource $resource): static;
/**
* set resources
*
- * @param OCMResource[] $resourceTypes
+ * @param IOCMResource[] $resourceTypes
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function setResourceTypes(array $resourceTypes): self;
+ public function setResourceTypes(array $resourceTypes): static;
/**
* get all set resources
@@ -135,9 +142,24 @@ public function extractProtocolEntry(string $resourceName, string $protocol): st
*
* @param array $data
*
- * @return self
+ * @return $this
* @throws OCMProviderException in case a descent provider cannot be generated from data
* @since 28.0.0
*/
- public function import(array $data): self;
+ public function import(array $data): static;
+
+ /**
+ * @return array{
+ * enabled: bool,
+ * apiVersion: string,
+ * endPoint: string,
+ * resourceTypes: array{
+ * name: string,
+ * shareTypes: string[],
+ * protocols: array
+ * }[]
+ * }
+ * @since 28.0.0
+ */
+ public function jsonSerialize(): array;
}
diff --git a/lib/public/OCM/IOCMResource.php b/lib/public/OCM/IOCMResource.php
index 381af61cecc4c..242c77116f194 100644
--- a/lib/public/OCM/IOCMResource.php
+++ b/lib/public/OCM/IOCMResource.php
@@ -26,22 +26,24 @@
namespace OCP\OCM;
+use JsonSerializable;
+
/**
* Model based on the Open Cloud Mesh Discovery API
*
* @link https://github.com/cs3org/OCM-API/
* @since 28.0.0
*/
-interface IOCMResource {
+interface IOCMResource extends JsonSerializable {
/**
* set name of the resource
*
* @param string $name
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function setName(string $name): self;
+ public function setName(string $name): static;
/**
* get name of the resource
@@ -56,10 +58,10 @@ public function getName(): string;
*
* @param string[] $shareTypes
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function setShareTypes(array $shareTypes): self;
+ public function setShareTypes(array $shareTypes): static;
/**
* get share types
@@ -74,10 +76,10 @@ public function getShareTypes(): array;
*
* @param array $protocols
*
- * @return self
+ * @return $this
* @since 28.0.0
*/
- public function setProtocols(array $protocols): self;
+ public function setProtocols(array $protocols): static;
/**
* get configured protocols
@@ -92,8 +94,18 @@ public function getProtocols(): array;
*
* @param array $data
*
- * @return self
+ * @return $this
+ * @since 28.0.0
+ */
+ public function import(array $data): static;
+
+ /**
+ * @return array{
+ * name: string,
+ * shareTypes: string[],
+ * protocols: array
+ * }
* @since 28.0.0
*/
- public function import(array $data): self;
+ public function jsonSerialize(): array;
}