mirror of https://github.com/nextcloud/server
ocm controller
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
This commit is contained in:
parent
d5fc95b661
commit
8b9e7e235d
|
@ -6,6 +6,7 @@ declare(strict_types=1);
|
|||
* @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -27,15 +28,21 @@ return [
|
|||
'routes' => [
|
||||
[
|
||||
'name' => 'RequestHandler#addShare',
|
||||
'url' => '/ocm/shares',
|
||||
'url' => '/shares',
|
||||
'verb' => 'POST',
|
||||
'root' => '',
|
||||
'root' => '/ocm',
|
||||
],
|
||||
[
|
||||
'name' => 'RequestHandler#receiveNotification',
|
||||
'url' => '/ocm/notifications',
|
||||
'url' => '/notifications',
|
||||
'verb' => 'POST',
|
||||
'root' => '',
|
||||
'root' => '/ocm',
|
||||
],
|
||||
// [
|
||||
// 'name' => 'RequestHandler#inviteAccepted',
|
||||
// 'url' => '/invite-accepted',
|
||||
// 'verb' => 'POST',
|
||||
// 'root' => '/ocm',
|
||||
// ]
|
||||
],
|
||||
];
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
|
||||
*
|
||||
* @author Bjoern Schiessle <bjoern@schiessle.org>
|
||||
* @author Kate Döen <kate.doeen@nextcloud.com>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -21,18 +25,22 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
class Capabilities implements ICapability {
|
||||
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
public const API_VERSION = '1.0-proposal1';
|
||||
|
||||
public function __construct(IURLGenerator $urlGenerator) {
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
public function __construct(
|
||||
private IURLGenerator $urlGenerator,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,32 +54,33 @@ class Capabilities implements ICapability {
|
|||
* resourceTypes: array{
|
||||
* name: string,
|
||||
* shareTypes: string[],
|
||||
* protocols: array{
|
||||
* webdav: string,
|
||||
* },
|
||||
* }[],
|
||||
* },
|
||||
* protocols: array<string, string>
|
||||
* }[],
|
||||
* },
|
||||
* }
|
||||
* @throws OCMArgumentException
|
||||
*/
|
||||
public function getCapabilities() {
|
||||
$url = $this->urlGenerator->linkToRouteAbsolute('cloud_federation_api.requesthandlercontroller.addShare');
|
||||
$capabilities = ['ocm' =>
|
||||
[
|
||||
'enabled' => true,
|
||||
'apiVersion' => '1.0-proposal1',
|
||||
'endPoint' => substr($url, 0, strrpos($url, '/')),
|
||||
'resourceTypes' => [
|
||||
[
|
||||
'name' => 'file',
|
||||
'shareTypes' => ['user', 'group'],
|
||||
'protocols' => [
|
||||
'webdav' => '/public.php/webdav/',
|
||||
]
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
return $capabilities;
|
||||
$provider = new OCMProvider();
|
||||
$provider->setEnabled(true);
|
||||
$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));
|
||||
|
||||
$resource = new OCMResource();
|
||||
$resource->setName('file')
|
||||
->setShareTypes(['user', 'group'])
|
||||
->setProtocols(['webdav' => '/public.php/webdav/']);
|
||||
|
||||
$provider->setResourceTypes([$resource]);
|
||||
|
||||
return ['ocm' => $provider->jsonSerialize()];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*
|
||||
* @author Bjoern Schiessle <bjoern@schiessle.org>
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
* @author Kate Döen <kate.doeen@nextcloud.com>
|
||||
*
|
||||
|
@ -55,52 +56,19 @@ use Psr\Log\LoggerInterface;
|
|||
* @psalm-import-type CloudFederationApiError from ResponseDefinitions
|
||||
*/
|
||||
class RequestHandlerController extends Controller {
|
||||
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var IGroupManager */
|
||||
private $groupManager;
|
||||
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
|
||||
/** @var ICloudFederationProviderManager */
|
||||
private $cloudFederationProviderManager;
|
||||
|
||||
/** @var Config */
|
||||
private $config;
|
||||
|
||||
/** @var ICloudFederationFactory */
|
||||
private $factory;
|
||||
|
||||
/** @var ICloudIdManager */
|
||||
private $cloudIdManager;
|
||||
|
||||
public function __construct($appName,
|
||||
IRequest $request,
|
||||
LoggerInterface $logger,
|
||||
IUserManager $userManager,
|
||||
IGroupManager $groupManager,
|
||||
IURLGenerator $urlGenerator,
|
||||
ICloudFederationProviderManager $cloudFederationProviderManager,
|
||||
Config $config,
|
||||
ICloudFederationFactory $factory,
|
||||
ICloudIdManager $cloudIdManager
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private LoggerInterface $logger,
|
||||
private IUserManager $userManager,
|
||||
private IGroupManager $groupManager,
|
||||
private IURLGenerator $urlGenerator,
|
||||
private ICloudFederationProviderManager $cloudFederationProviderManager,
|
||||
private Config $config,
|
||||
private ICloudFederationFactory $factory,
|
||||
private ICloudIdManager $cloudIdManager
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
|
||||
$this->logger = $logger;
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->cloudFederationProviderManager = $cloudFederationProviderManager;
|
||||
$this->config = $config;
|
||||
$this->factory = $factory;
|
||||
$this->cloudIdManager = $cloudIdManager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +96,6 @@ class RequestHandlerController extends Controller {
|
|||
* 501: Share type or the resource type is not supported
|
||||
*/
|
||||
public function addShare($shareWith, $name, $description, $providerId, $owner, $ownerDisplayName, $sharedBy, $sharedByDisplayName, $protocol, $shareType, $resourceType) {
|
||||
|
||||
// check if all required parameters are set
|
||||
if ($shareWith === null ||
|
||||
$name === null ||
|
||||
|
@ -253,7 +220,6 @@ class RequestHandlerController extends Controller {
|
|||
* 501: The resource type is not supported
|
||||
*/
|
||||
public function receiveNotification($notificationType, $resourceType, $providerId, ?array $notification) {
|
||||
|
||||
// check if all required parameters are set
|
||||
if ($notificationType === null ||
|
||||
$resourceType === null ||
|
||||
|
@ -311,7 +277,7 @@ class RequestHandlerController extends Controller {
|
|||
);
|
||||
}
|
||||
|
||||
return new JSONResponse($result,Http::STATUS_CREATED);
|
||||
return new JSONResponse($result, Http::STATUS_CREATED);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -76,13 +76,8 @@
|
|||
},
|
||||
"protocols": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"webdav"
|
||||
],
|
||||
"properties": {
|
||||
"webdav": {
|
||||
"type": "string"
|
||||
}
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ declare(strict_types=1);
|
|||
* @copyright 2018, Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
|
@ -29,21 +30,19 @@ namespace OCA\Files_Sharing\BackgroundJob;
|
|||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\OCM\Exceptions\OCMProviderException;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use OCP\OCS\IDiscoveryService;
|
||||
|
||||
class FederatedSharesDiscoverJob extends TimedJob {
|
||||
/** @var IDBConnection */
|
||||
private $connection;
|
||||
/** @var IDiscoveryService */
|
||||
private $discoveryService;
|
||||
|
||||
public function __construct(ITimeFactory $time,
|
||||
IDBConnection $connection,
|
||||
IDiscoveryService $discoveryService) {
|
||||
public function __construct(
|
||||
ITimeFactory $time,
|
||||
private IDBConnection $connection,
|
||||
private IDiscoveryService $discoveryService,
|
||||
private IOCMDiscoveryService $ocmDiscoveryService
|
||||
) {
|
||||
parent::__construct($time);
|
||||
$this->connection = $connection;
|
||||
$this->discoveryService = $discoveryService;
|
||||
|
||||
$this->setInterval(86400);
|
||||
}
|
||||
|
||||
|
@ -56,6 +55,10 @@ class FederatedSharesDiscoverJob extends TimedJob {
|
|||
$result = $qb->execute();
|
||||
while ($row = $result->fetch()) {
|
||||
$this->discoveryService->discover($row['remote'], 'FEDERATED_SHARING', true);
|
||||
try {
|
||||
$this->ocmDiscoveryService->discover($row['remote'], true);
|
||||
} catch (OCMProviderException $e) {
|
||||
}
|
||||
}
|
||||
$result->closeCursor();
|
||||
}
|
||||
|
|
|
@ -134,14 +134,14 @@ class ExternalSharesController extends Controller {
|
|||
}
|
||||
|
||||
if (
|
||||
$this->testUrl('https://' . $remote . '/ocs-provider/') ||
|
||||
$this->testUrl('https://' . $remote . '/ocs-provider/index.php') ||
|
||||
$this->testUrl('https://' . $remote . '/ocm-provider/') ||
|
||||
$this->testUrl('https://' . $remote . '/ocm-provider/index.php') ||
|
||||
$this->testUrl('https://' . $remote . '/status.php', true)
|
||||
) {
|
||||
return new DataResponse('https');
|
||||
} elseif (
|
||||
$this->testUrl('http://' . $remote . '/ocs-provider/') ||
|
||||
$this->testUrl('http://' . $remote . '/ocs-provider/index.php') ||
|
||||
$this->testUrl('http://' . $remote . '/ocm-provider/') ||
|
||||
$this->testUrl('http://' . $remote . '/ocm-provider/index.php') ||
|
||||
$this->testUrl('http://' . $remote . '/status.php', true)
|
||||
) {
|
||||
return new DataResponse('http');
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
|
@ -8,6 +11,7 @@
|
|||
* @author Daniel Kesselberg <mail@danielkesselberg.de>
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Lukas Reschke <lukas@statuscode.ch>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin Appelman <robin@icewind.nl>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
|
@ -36,8 +40,8 @@ use GuzzleHttp\Exception\ConnectException;
|
|||
use GuzzleHttp\Exception\RequestException;
|
||||
use OC\Files\Storage\DAV;
|
||||
use OC\ForbiddenException;
|
||||
use OCA\Files_Sharing\ISharedStorage;
|
||||
use OCA\Files_Sharing\External\Manager as ExternalShareManager;
|
||||
use OCA\Files_Sharing\ISharedStorage;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\Constants;
|
||||
use OCP\Federation\ICloudId;
|
||||
|
@ -46,25 +50,23 @@ use OCP\Files\Storage\IDisableEncryptionStorage;
|
|||
use OCP\Files\Storage\IReliableEtagStorage;
|
||||
use OCP\Files\StorageInvalidException;
|
||||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCP\Http\Client\LocalServerException;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\Http\Client\LocalServerException;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\OCM\Exceptions\OCMArgumentException;
|
||||
use OCP\OCM\Exceptions\OCMProviderException;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage, IReliableEtagStorage {
|
||||
/** @var ICloudId */
|
||||
private $cloudId;
|
||||
/** @var string */
|
||||
private $mountPoint;
|
||||
/** @var string */
|
||||
private $token;
|
||||
/** @var \OCP\ICacheFactory */
|
||||
private $memcacheFactory;
|
||||
/** @var \OCP\Http\Client\IClientService */
|
||||
private $httpClient;
|
||||
/** @var bool */
|
||||
private $updateChecked = false;
|
||||
|
||||
/** @var ExternalShareManager */
|
||||
private $manager;
|
||||
private ICloudId $cloudId;
|
||||
private string $mountPoint;
|
||||
private string $token;
|
||||
private ICacheFactory $memcacheFactory;
|
||||
private IClientService $httpClient;
|
||||
private bool $updateChecked = false;
|
||||
private ExternalShareManager $manager;
|
||||
|
||||
/**
|
||||
* @param array{HttpClientService: IClientService, manager: ExternalShareManager, cloudId: ICloudId, mountpoint: string, token: string, password: ?string}|array $options
|
||||
|
@ -72,32 +74,44 @@ class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage,
|
|||
public function __construct($options) {
|
||||
$this->memcacheFactory = \OC::$server->getMemCacheFactory();
|
||||
$this->httpClient = $options['HttpClientService'];
|
||||
|
||||
$this->manager = $options['manager'];
|
||||
$this->cloudId = $options['cloudId'];
|
||||
$discoveryService = \OC::$server->query(\OCP\OCS\IDiscoveryService::class);
|
||||
$this->logger = Server::get(LoggerInterface::class);
|
||||
$discoveryService = Server::get(IOCMDiscoveryService::class);
|
||||
|
||||
[$protocol, $remote] = explode('://', $this->cloudId->getRemote());
|
||||
if (str_contains($remote, '/')) {
|
||||
[$host, $root] = explode('/', $remote, 2);
|
||||
} else {
|
||||
$host = $remote;
|
||||
$root = '';
|
||||
// use default path to webdav if not found on discovery
|
||||
try {
|
||||
$ocmProvider = $discoveryService->discover($this->cloudId->getRemote());
|
||||
$webDavEndpoint = $ocmProvider->extractProtocolEntry('file', 'webdav');
|
||||
$remote = $ocmProvider->getEndPoint();
|
||||
} catch (OCMProviderException|OCMArgumentException $e) {
|
||||
$this->logger->notice('exception while retrieving webdav endpoint', ['exception' => $e]);
|
||||
$webDavEndpoint = '/public.php/webdav';
|
||||
$remote = $this->cloudId->getRemote();
|
||||
}
|
||||
$secure = $protocol === 'https';
|
||||
$federatedSharingEndpoints = $discoveryService->discover($this->cloudId->getRemote(), 'FEDERATED_SHARING');
|
||||
$webDavEndpoint = isset($federatedSharingEndpoints['webdav']) ? $federatedSharingEndpoints['webdav'] : '/public.php/webdav';
|
||||
$root = rtrim($root, '/') . $webDavEndpoint;
|
||||
|
||||
$host = parse_url($remote, PHP_URL_HOST);
|
||||
$port = parse_url($remote, PHP_URL_PORT);
|
||||
$host .= (null === $port) ? '' : ':' . $port; // we add port if available
|
||||
|
||||
// in case remote NC is on a sub folder and using deprecated ocm provider
|
||||
$tmpPath = rtrim(parse_url($this->cloudId->getRemote(), PHP_URL_PATH) ?? '', '/');
|
||||
if (!str_starts_with($webDavEndpoint, $tmpPath)) {
|
||||
$webDavEndpoint = $tmpPath . $webDavEndpoint;
|
||||
}
|
||||
|
||||
$this->mountPoint = $options['mountpoint'];
|
||||
$this->token = $options['token'];
|
||||
|
||||
parent::__construct([
|
||||
'secure' => $secure,
|
||||
'host' => $host,
|
||||
'root' => $root,
|
||||
'user' => $options['token'],
|
||||
'password' => (string)$options['password']
|
||||
]);
|
||||
parent::__construct(
|
||||
[
|
||||
'secure' => ((parse_url($remote, PHP_URL_SCHEME) ?? 'https') === 'https'),
|
||||
'host' => $host,
|
||||
'root' => $webDavEndpoint,
|
||||
'user' => $options['token'],
|
||||
'password' => (string)$options['password']
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function getWatcher($path = '', $storage = null) {
|
||||
|
@ -255,9 +269,9 @@ class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage,
|
|||
*/
|
||||
protected function testRemote(): bool {
|
||||
try {
|
||||
return $this->testRemoteUrl($this->getRemote() . '/ocs-provider/index.php')
|
||||
|| $this->testRemoteUrl($this->getRemote() . '/ocs-provider/')
|
||||
|| $this->testRemoteUrl($this->getRemote() . '/status.php');
|
||||
return $this->testRemoteUrl($this->getRemote() . '/ocm-provider/index.php')
|
||||
|| $this->testRemoteUrl($this->getRemote() . '/ocm-provider/')
|
||||
|| $this->testRemoteUrl($this->getRemote() . '/status.php');
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
namespace OCA\Files_Sharing\Tests;
|
||||
|
||||
use OC\Federation\CloudId;
|
||||
use OCA\Files_Sharing\External\Manager as ExternalShareManager;
|
||||
use OCP\Http\Client\IClient;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\Http\Client\IResponse;
|
||||
|
@ -75,6 +76,7 @@ class ExternalStorageTest extends \Test\TestCase {
|
|||
private function getTestStorage($uri) {
|
||||
$certificateManager = \OC::$server->getCertificateManager();
|
||||
$httpClientService = $this->createMock(IClientService::class);
|
||||
$manager = $this->createMock(ExternalShareManager::class);
|
||||
$client = $this->createMock(IClient::class);
|
||||
$response = $this->createMock(IResponse::class);
|
||||
$client
|
||||
|
@ -98,7 +100,7 @@ class ExternalStorageTest extends \Test\TestCase {
|
|||
'mountpoint' => 'remoteshare',
|
||||
'token' => 'abcdef',
|
||||
'password' => '',
|
||||
'manager' => null,
|
||||
'manager' => $manager,
|
||||
'certificateManager' => $certificateManager,
|
||||
'HttpClientService' => $httpClientService,
|
||||
]
|
||||
|
|
|
@ -79,7 +79,6 @@ $expectedFiles = [
|
|||
'jest.config.ts',
|
||||
'lib',
|
||||
'occ',
|
||||
'ocm-provider',
|
||||
'ocs',
|
||||
'ocs-provider',
|
||||
'package-lock.json',
|
||||
|
|
|
@ -43,6 +43,11 @@
|
|||
<code>IEventListener</code>
|
||||
</MissingTemplateParam>
|
||||
</file>
|
||||
<file src="apps/cloud_federation_api/lib/Capabilities.php">
|
||||
<LessSpecificImplementedReturnType>
|
||||
<code>array</code>
|
||||
</LessSpecificImplementedReturnType>
|
||||
</file>
|
||||
<file src="apps/comments/lib/Listener/CommentsEntityEventListener.php">
|
||||
<MissingTemplateParam>
|
||||
<code>IEventListener</code>
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OC\Core\Controller;
|
||||
|
||||
use Exception;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\Server;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Controller about the endpoint /ocm-provider/
|
||||
*
|
||||
* @since 28.0.0
|
||||
*/
|
||||
class OCMController extends Controller {
|
||||
public function __construct(
|
||||
IRequest $request,
|
||||
private IConfig $config,
|
||||
private LoggerInterface $logger
|
||||
) {
|
||||
parent::__construct('core', $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate a OCMProvider with local data and send it as DataResponse.
|
||||
* This replaces the old PHP file ocm-provider/index.php
|
||||
*
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
#[IgnoreOpenAPI]
|
||||
public function discovery(): Response {
|
||||
try {
|
||||
$cap = Server::get(
|
||||
$this->config->getAppValue(
|
||||
'core',
|
||||
'ocm_providers',
|
||||
'\OCA\CloudFederationAPI\Capabilities'
|
||||
)
|
||||
);
|
||||
|
||||
return new DataResponse(
|
||||
$cap->getCapabilities()['ocm'] ?? ['enabled' => false],
|
||||
Http::STATUS_OK,
|
||||
[
|
||||
'X-NEXTCLOUD-OCM-PROVIDERS' => true,
|
||||
'Content-Type' => 'application/json'
|
||||
]
|
||||
);
|
||||
} catch (ContainerExceptionInterface|Exception $e) {
|
||||
$this->logger->error('issue during OCM discovery request', ['exception' => $e]);
|
||||
|
||||
return new DataResponse(
|
||||
['message' => '/ocm-provider/ not supported'],
|
||||
Http::STATUS_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4988,6 +4988,10 @@
|
|||
{
|
||||
"name": "guest_avatar",
|
||||
"description": "This controller handles guest avatar requests."
|
||||
},
|
||||
{
|
||||
"name": "ocm",
|
||||
"description": "Controller about the endpoint /ocm-provider/"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -13,6 +13,7 @@ declare(strict_types=1);
|
|||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Lukas Reschke <lukas@statuscode.ch>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @author Michael Weimann <mail@michael-weimann.eu>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
|
@ -103,6 +104,9 @@ $application->registerRoutes($this, [
|
|||
// Well known requests https://tools.ietf.org/html/rfc5785
|
||||
['name' => 'WellKnown#handle', 'url' => '.well-known/{service}'],
|
||||
|
||||
// OCM Provider requests https://github.com/cs3org/OCM-API
|
||||
['name' => 'OCM#discovery', 'url' => '/ocm-provider/'],
|
||||
|
||||
// Unsupported browser
|
||||
['name' => 'UnsupportedBrowser#index', 'url' => 'unsupported'],
|
||||
],
|
||||
|
|
|
@ -536,6 +536,11 @@ return array(
|
|||
'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\\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',
|
||||
'OCP\\OCM\\IOCMProvider' => $baseDir . '/lib/public/OCM/IOCMProvider.php',
|
||||
'OCP\\OCM\\IOCMResource' => $baseDir . '/lib/public/OCM/IOCMResource.php',
|
||||
'OCP\\OCS\\IDiscoveryService' => $baseDir . '/lib/public/OCS/IDiscoveryService.php',
|
||||
'OCP\\PreConditionNotMetException' => $baseDir . '/lib/public/PreConditionNotMetException.php',
|
||||
'OCP\\Preview\\BeforePreviewFetchedEvent' => $baseDir . '/lib/public/Preview/BeforePreviewFetchedEvent.php',
|
||||
|
@ -1074,6 +1079,7 @@ return array(
|
|||
'OC\\Core\\Controller\\LostController' => $baseDir . '/core/Controller/LostController.php',
|
||||
'OC\\Core\\Controller\\NavigationController' => $baseDir . '/core/Controller/NavigationController.php',
|
||||
'OC\\Core\\Controller\\OCJSController' => $baseDir . '/core/Controller/OCJSController.php',
|
||||
'OC\\Core\\Controller\\OCMController' => $baseDir . '/core/Controller/OCMController.php',
|
||||
'OC\\Core\\Controller\\OCSController' => $baseDir . '/core/Controller/OCSController.php',
|
||||
'OC\\Core\\Controller\\PreviewController' => $baseDir . '/core/Controller/PreviewController.php',
|
||||
'OC\\Core\\Controller\\ProfileApiController' => $baseDir . '/core/Controller/ProfileApiController.php',
|
||||
|
@ -1463,6 +1469,9 @@ return array(
|
|||
'OC\\Notification\\Action' => $baseDir . '/lib/private/Notification/Action.php',
|
||||
'OC\\Notification\\Manager' => $baseDir . '/lib/private/Notification/Manager.php',
|
||||
'OC\\Notification\\Notification' => $baseDir . '/lib/private/Notification/Notification.php',
|
||||
'OC\\OCM\\Model\\OCMProvider' => $baseDir . '/lib/private/OCM/Model/OCMProvider.php',
|
||||
'OC\\OCM\\Model\\OCMResource' => $baseDir . '/lib/private/OCM/Model/OCMResource.php',
|
||||
'OC\\OCM\\OCMDiscoveryService' => $baseDir . '/lib/private/OCM/OCMDiscoveryService.php',
|
||||
'OC\\OCS\\CoreCapabilities' => $baseDir . '/lib/private/OCS/CoreCapabilities.php',
|
||||
'OC\\OCS\\DiscoveryService' => $baseDir . '/lib/private/OCS/DiscoveryService.php',
|
||||
'OC\\OCS\\Exception' => $baseDir . '/lib/private/OCS/Exception.php',
|
||||
|
|
|
@ -569,6 +569,11 @@ 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\\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',
|
||||
'OCP\\OCM\\IOCMProvider' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMProvider.php',
|
||||
'OCP\\OCM\\IOCMResource' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMResource.php',
|
||||
'OCP\\OCS\\IDiscoveryService' => __DIR__ . '/../../..' . '/lib/public/OCS/IDiscoveryService.php',
|
||||
'OCP\\PreConditionNotMetException' => __DIR__ . '/../../..' . '/lib/public/PreConditionNotMetException.php',
|
||||
'OCP\\Preview\\BeforePreviewFetchedEvent' => __DIR__ . '/../../..' . '/lib/public/Preview/BeforePreviewFetchedEvent.php',
|
||||
|
@ -1107,6 +1112,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Core\\Controller\\LostController' => __DIR__ . '/../../..' . '/core/Controller/LostController.php',
|
||||
'OC\\Core\\Controller\\NavigationController' => __DIR__ . '/../../..' . '/core/Controller/NavigationController.php',
|
||||
'OC\\Core\\Controller\\OCJSController' => __DIR__ . '/../../..' . '/core/Controller/OCJSController.php',
|
||||
'OC\\Core\\Controller\\OCMController' => __DIR__ . '/../../..' . '/core/Controller/OCMController.php',
|
||||
'OC\\Core\\Controller\\OCSController' => __DIR__ . '/../../..' . '/core/Controller/OCSController.php',
|
||||
'OC\\Core\\Controller\\PreviewController' => __DIR__ . '/../../..' . '/core/Controller/PreviewController.php',
|
||||
'OC\\Core\\Controller\\ProfileApiController' => __DIR__ . '/../../..' . '/core/Controller/ProfileApiController.php',
|
||||
|
@ -1496,6 +1502,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Notification\\Action' => __DIR__ . '/../../..' . '/lib/private/Notification/Action.php',
|
||||
'OC\\Notification\\Manager' => __DIR__ . '/../../..' . '/lib/private/Notification/Manager.php',
|
||||
'OC\\Notification\\Notification' => __DIR__ . '/../../..' . '/lib/private/Notification/Notification.php',
|
||||
'OC\\OCM\\Model\\OCMProvider' => __DIR__ . '/../../..' . '/lib/private/OCM/Model/OCMProvider.php',
|
||||
'OC\\OCM\\Model\\OCMResource' => __DIR__ . '/../../..' . '/lib/private/OCM/Model/OCMResource.php',
|
||||
'OC\\OCM\\OCMDiscoveryService' => __DIR__ . '/../../..' . '/lib/private/OCM/OCMDiscoveryService.php',
|
||||
'OC\\OCS\\CoreCapabilities' => __DIR__ . '/../../..' . '/lib/private/OCS/CoreCapabilities.php',
|
||||
'OC\\OCS\\DiscoveryService' => __DIR__ . '/../../..' . '/lib/private/OCS/DiscoveryService.php',
|
||||
'OC\\OCS\\Exception' => __DIR__ . '/../../..' . '/lib/private/OCS/Exception.php',
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Bjoern Schiessle <bjoern@schiessle.org>
|
||||
*
|
||||
* @author Bjoern Schiessle <bjoern@schiessle.org>
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -32,6 +36,9 @@ use OCP\Federation\ICloudFederationProviderManager;
|
|||
use OCP\Federation\ICloudFederationShare;
|
||||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\IConfig;
|
||||
use OCP\OCM\Exceptions\OCMProviderException;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
|
@ -43,40 +50,16 @@ use Psr\Log\LoggerInterface;
|
|||
*/
|
||||
class CloudFederationProviderManager implements ICloudFederationProviderManager {
|
||||
/** @var array list of available cloud federation providers */
|
||||
private $cloudFederationProvider;
|
||||
private array $cloudFederationProvider = [];
|
||||
|
||||
/** @var IAppManager */
|
||||
private $appManager;
|
||||
|
||||
/** @var IClientService */
|
||||
private $httpClientService;
|
||||
|
||||
/** @var ICloudIdManager */
|
||||
private $cloudIdManager;
|
||||
|
||||
private LoggerInterface $logger;
|
||||
|
||||
/** @var array cache OCM end-points */
|
||||
private $ocmEndPoints = [];
|
||||
|
||||
private $supportedAPIVersion = '1.0-proposal1';
|
||||
|
||||
/**
|
||||
* CloudFederationProviderManager constructor.
|
||||
*
|
||||
* @param IAppManager $appManager
|
||||
* @param IClientService $httpClientService
|
||||
* @param ICloudIdManager $cloudIdManager
|
||||
*/
|
||||
public function __construct(IAppManager $appManager,
|
||||
IClientService $httpClientService,
|
||||
ICloudIdManager $cloudIdManager,
|
||||
LoggerInterface $logger) {
|
||||
$this->cloudFederationProvider = [];
|
||||
$this->appManager = $appManager;
|
||||
$this->httpClientService = $httpClientService;
|
||||
$this->cloudIdManager = $cloudIdManager;
|
||||
$this->logger = $logger;
|
||||
public function __construct(
|
||||
private IConfig $config,
|
||||
private IAppManager $appManager,
|
||||
private IClientService $httpClientService,
|
||||
private ICloudIdManager $cloudIdManager,
|
||||
private IOCMDiscoveryService $discoveryService,
|
||||
private LoggerInterface $logger
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,16 +113,18 @@ class CloudFederationProviderManager implements ICloudFederationProviderManager
|
|||
|
||||
public function sendShare(ICloudFederationShare $share) {
|
||||
$cloudID = $this->cloudIdManager->resolveCloudId($share->getShareWith());
|
||||
$ocmEndPoint = $this->getOCMEndPoint($cloudID->getRemote());
|
||||
if (empty($ocmEndPoint)) {
|
||||
try {
|
||||
$ocmProvider = $this->discoveryService->discover($cloudID->getRemote());
|
||||
} catch (OCMProviderException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = $this->httpClientService->newClient();
|
||||
try {
|
||||
$response = $client->post($ocmEndPoint . '/shares', [
|
||||
$response = $client->post($ocmProvider->getEndPoint() . '/shares', [
|
||||
'body' => json_encode($share->getShare()),
|
||||
'headers' => ['content-type' => 'application/json'],
|
||||
'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates', false),
|
||||
'timeout' => 10,
|
||||
'connect_timeout' => 10,
|
||||
]);
|
||||
|
@ -168,17 +153,18 @@ class CloudFederationProviderManager implements ICloudFederationProviderManager
|
|||
* @return array|false
|
||||
*/
|
||||
public function sendNotification($url, ICloudFederationNotification $notification) {
|
||||
$ocmEndPoint = $this->getOCMEndPoint($url);
|
||||
|
||||
if (empty($ocmEndPoint)) {
|
||||
try {
|
||||
$ocmProvider = $this->discoveryService->discover($url);
|
||||
} catch (OCMProviderException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = $this->httpClientService->newClient();
|
||||
try {
|
||||
$response = $client->post($ocmEndPoint . '/notifications', [
|
||||
$response = $client->post($ocmProvider->getEndPoint() . '/notifications', [
|
||||
'body' => json_encode($notification->getMessage()),
|
||||
'headers' => ['content-type' => 'application/json'],
|
||||
'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates', false),
|
||||
'timeout' => 10,
|
||||
'connect_timeout' => 10,
|
||||
]);
|
||||
|
@ -202,36 +188,4 @@ class CloudFederationProviderManager implements ICloudFederationProviderManager
|
|||
public function isReady() {
|
||||
return $this->appManager->isEnabledForUser('cloud_federation_api');
|
||||
}
|
||||
/**
|
||||
* check if server supports the new OCM api and ask for the correct end-point
|
||||
*
|
||||
* @param string $url full base URL of the cloud server
|
||||
* @return string
|
||||
*/
|
||||
protected function getOCMEndPoint($url) {
|
||||
if (isset($this->ocmEndPoints[$url])) {
|
||||
return $this->ocmEndPoints[$url];
|
||||
}
|
||||
|
||||
$client = $this->httpClientService->newClient();
|
||||
try {
|
||||
$response = $client->get($url . '/ocm-provider/', ['timeout' => 10, 'connect_timeout' => 10]);
|
||||
} catch (\Exception $e) {
|
||||
$this->ocmEndPoints[$url] = '';
|
||||
return '';
|
||||
}
|
||||
|
||||
$result = $response->getBody();
|
||||
$result = json_decode($result, true);
|
||||
|
||||
$supportedVersion = isset($result['apiVersion']) && $result['apiVersion'] === $this->supportedAPIVersion;
|
||||
|
||||
if (isset($result['endPoint']) && $supportedVersion) {
|
||||
$this->ocmEndPoints[$url] = $result['endPoint'];
|
||||
return $result['endPoint'];
|
||||
}
|
||||
|
||||
$this->ocmEndPoints[$url] = '';
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OC\OCM\Model;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCP\OCM\Exceptions\OCMArgumentException;
|
||||
use OCP\OCM\Exceptions\OCMProviderException;
|
||||
use OCP\OCM\IOCMProvider;
|
||||
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
class OCMProvider implements IOCMProvider, JsonSerializable {
|
||||
private bool $enabled = false;
|
||||
private string $apiVersion = '';
|
||||
private string $endPoint = '';
|
||||
/** @var OCMResource[] */
|
||||
private array $resourceTypes = [];
|
||||
|
||||
/**
|
||||
* @param bool $enabled
|
||||
*
|
||||
* @return OCMProvider
|
||||
*/
|
||||
public function setEnabled(bool $enabled): self {
|
||||
$this->enabled = $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled(): bool {
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $apiVersion
|
||||
*
|
||||
* @return OCMProvider
|
||||
*/
|
||||
public function setApiVersion(string $apiVersion): self {
|
||||
$this->apiVersion = $apiVersion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getApiVersion(): string {
|
||||
return $this->apiVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $endPoint
|
||||
*
|
||||
* @return OCMProvider
|
||||
*/
|
||||
public function setEndPoint(string $endPoint): self {
|
||||
$this->endPoint = $endPoint;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEndPoint(): string {
|
||||
return $this->endPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OCMResource $resource
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addResourceType(OCMResource $resource): self {
|
||||
$this->resourceTypes[] = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OCMResource[] $resourceTypes
|
||||
*
|
||||
* @return OCMProvider
|
||||
*/
|
||||
public function setResourceTypes(array $resourceTypes): self {
|
||||
$this->resourceTypes = $resourceTypes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OCMResource[]
|
||||
*/
|
||||
public function getResourceTypes(): array {
|
||||
return $this->resourceTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resourceName
|
||||
* @param string $protocol
|
||||
*
|
||||
* @return string
|
||||
* @throws OCMArgumentException
|
||||
*/
|
||||
public function extractProtocolEntry(string $resourceName, string $protocol): string {
|
||||
foreach ($this->getResourceTypes() as $resource) {
|
||||
if ($resource->getName() === $resourceName) {
|
||||
$entry = $resource->getProtocols()[$protocol] ?? null;
|
||||
if (is_null($entry)) {
|
||||
throw new OCMArgumentException('protocol not found');
|
||||
}
|
||||
|
||||
return (string)$entry;
|
||||
}
|
||||
}
|
||||
|
||||
throw new OCMArgumentException('resource not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* import data from an array
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return self
|
||||
* @throws OCMProviderException in case a descent provider cannot be generated from data
|
||||
* @see self::jsonSerialize()
|
||||
*/
|
||||
public function import(array $data): self {
|
||||
$this->setEnabled(is_bool($data['enabled'] ?? '') ? $data['enabled'] : false)
|
||||
->setApiVersion((string)($data['apiVersion'] ?? ''))
|
||||
->setEndPoint($data['endPoint'] ?? '');
|
||||
|
||||
$resources = [];
|
||||
foreach (($data['resourceTypes'] ?? []) as $resourceData) {
|
||||
$resource = new OCMResource();
|
||||
$resources[] = $resource->import($resourceData);
|
||||
}
|
||||
$this->setResourceTypes($resources);
|
||||
|
||||
if (!$this->looksValid()) {
|
||||
throw new OCMProviderException('remote provider does not look valid');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function looksValid(): bool {
|
||||
return ($this->getApiVersion() !== '' && $this->getEndPoint() !== '');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* enabled: bool,
|
||||
* apiVersion: string,
|
||||
* endPoint: string,
|
||||
* resourceTypes: array{
|
||||
* name: string,
|
||||
* shareTypes: string[],
|
||||
* protocols: array<string, string>
|
||||
* }[]
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
$resourceTypes = []; // this is needed for psalm
|
||||
foreach ($this->getResourceTypes() as $res) {
|
||||
$resourceTypes[] = $res->jsonSerialize();
|
||||
}
|
||||
|
||||
return [
|
||||
'enabled' => $this->isEnabled(),
|
||||
'apiVersion' => $this->getApiVersion(),
|
||||
'endPoint' => $this->getEndPoint(),
|
||||
'resourceTypes' => $resourceTypes
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OC\OCM\Model;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCP\OCM\IOCMResource;
|
||||
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
class OCMResource implements IOCMResource, JsonSerializable {
|
||||
private string $name = '';
|
||||
/** @var string[] */
|
||||
private array $shareTypes = [];
|
||||
/** @var array<string, string> */
|
||||
private array $protocols = [];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return OCMResource
|
||||
*/
|
||||
public function setName(string $name): self {
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $shareTypes
|
||||
*
|
||||
* @return OCMResource
|
||||
*/
|
||||
public function setShareTypes(array $shareTypes): self {
|
||||
$this->shareTypes = $shareTypes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getShareTypes(): array {
|
||||
return $this->shareTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $protocols
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setProtocols(array $protocols): self {
|
||||
$this->protocols = $protocols;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getProtocols(): array {
|
||||
return $this->protocols;
|
||||
}
|
||||
|
||||
/**
|
||||
* import data from an array
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return self
|
||||
* @see self::jsonSerialize()
|
||||
*/
|
||||
public function import(array $data): self {
|
||||
return $this->setName((string)($data['name'] ?? ''))
|
||||
->setShareTypes($data['shareTypes'] ?? [])
|
||||
->setProtocols($data['protocols'] ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array{
|
||||
* name: string,
|
||||
* shareTypes: string[],
|
||||
* protocols: array<string, string>
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
'name' => $this->getName(),
|
||||
'shareTypes' => $this->getShareTypes(),
|
||||
'protocols' => $this->getProtocols()
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OC\OCM;
|
||||
|
||||
use JsonException;
|
||||
use OC\OCM\Model\OCMProvider;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\Http\Client\IClientService;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\OCM\Exceptions\OCMProviderException;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use OCP\OCM\IOCMProvider;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
class OCMDiscoveryService implements IOCMDiscoveryService {
|
||||
private ICache $cache;
|
||||
private array $supportedAPIVersion =
|
||||
[
|
||||
'1.0-proposal1',
|
||||
'1.0',
|
||||
'1.1'
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
ICacheFactory $cacheFactory,
|
||||
private IClientService $clientService,
|
||||
private IConfig $config,
|
||||
private LoggerInterface $logger
|
||||
) {
|
||||
$this->cache = $cacheFactory->createDistributed('ocm-discovery');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $remote
|
||||
* @param bool $skipCache
|
||||
*
|
||||
* @return IOCMProvider
|
||||
* @throws OCMProviderException
|
||||
*/
|
||||
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
|
||||
}
|
||||
} catch (JsonException|OCMProviderException $e) {
|
||||
// we ignore cache on issues
|
||||
}
|
||||
}
|
||||
|
||||
$client = $this->clientService->newClient();
|
||||
try {
|
||||
$response = $client->get(
|
||||
$remote . '/ocm-provider/',
|
||||
[
|
||||
'timeout' => 10,
|
||||
'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'),
|
||||
'connect_timeout' => 10,
|
||||
]
|
||||
);
|
||||
|
||||
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->cache->set($remote, $body, 60 * 60 * 24);
|
||||
}
|
||||
} catch (JsonException|OCMProviderException $e) {
|
||||
throw new OCMProviderException('data returned by remote seems invalid - ' . ($body ?? ''));
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->warning('error while discovering ocm provider', [
|
||||
'exception' => $e,
|
||||
'remote' => $remote
|
||||
]);
|
||||
throw new OCMProviderException('error while requesting remote ocm provider');
|
||||
}
|
||||
|
||||
if (!$this->supportedAPIVersion($provider->getApiVersion())) {
|
||||
throw new OCMProviderException('API version not supported');
|
||||
}
|
||||
|
||||
return $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the version from remote is supported.
|
||||
* The minor version of the API will be ignored:
|
||||
* 1.0.1 is identified as 1.0
|
||||
*
|
||||
* @param string $version
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function supportedAPIVersion(string $version): bool {
|
||||
$dot1 = strpos($version, '.');
|
||||
$dot2 = strpos($version, '.', $dot1 + 1);
|
||||
|
||||
if ($dot2 > 0) {
|
||||
$version = substr($version, 0, $dot2);
|
||||
}
|
||||
|
||||
return (in_array($version, $this->supportedAPIVersion));
|
||||
}
|
||||
}
|
|
@ -124,6 +124,7 @@ use OC\Metadata\Capabilities as MetadataCapabilities;
|
|||
use OC\Metadata\IMetadataManager;
|
||||
use OC\Metadata\MetadataManager;
|
||||
use OC\Notification\Manager;
|
||||
use OC\OCM\OCMDiscoveryService;
|
||||
use OC\OCS\DiscoveryService;
|
||||
use OC\Preview\GeneratorHelper;
|
||||
use OC\Preview\IMagickSupport;
|
||||
|
@ -228,6 +229,7 @@ use OCP\Lock\ILockingProvider;
|
|||
use OCP\Lockdown\ILockdownManager;
|
||||
use OCP\Log\ILogFactory;
|
||||
use OCP\Mail\IMailer;
|
||||
use OCP\OCM\IOCMDiscoveryService;
|
||||
use OCP\Remote\Api\IApiFactory;
|
||||
use OCP\Remote\IInstanceFactory;
|
||||
use OCP\RichObjectStrings\IValidator;
|
||||
|
@ -1306,6 +1308,7 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
$c->get(IClientService::class)
|
||||
);
|
||||
});
|
||||
$this->registerAlias(IOCMDiscoveryService::class, OCMDiscoveryService::class);
|
||||
|
||||
$this->registerService(ICloudIdManager::class, function (ContainerInterface $c) {
|
||||
return new CloudIdManager(
|
||||
|
@ -1321,9 +1324,11 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
|
||||
$this->registerService(ICloudFederationProviderManager::class, function (ContainerInterface $c) {
|
||||
return new CloudFederationProviderManager(
|
||||
$c->get(\OCP\IConfig::class),
|
||||
$c->get(IAppManager::class),
|
||||
$c->get(IClientService::class),
|
||||
$c->get(ICloudIdManager::class),
|
||||
$c->get(IOCMDiscoveryService::class),
|
||||
$c->get(LoggerInterface::class)
|
||||
);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OCP\OCM\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
class OCMArgumentException extends Exception {
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OCP\OCM\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @since 28.0.0
|
||||
*/
|
||||
class OCMProviderException extends Exception {
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OCP\OCM;
|
||||
|
||||
use OCP\OCM\Exceptions\OCMProviderException;
|
||||
|
||||
/**
|
||||
* Discover remote OCM services
|
||||
*
|
||||
* @since 28.0.0
|
||||
*/
|
||||
interface IOCMDiscoveryService {
|
||||
/**
|
||||
* Discover remote OCM services
|
||||
*
|
||||
* @param string $remote address of the remote provider
|
||||
* @param bool $skipCache ignore cache, refresh data
|
||||
*
|
||||
* @return IOCMProvider
|
||||
* @throws OCMProviderException if no valid discovery data can be returned
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function discover(string $remote, bool $skipCache = false): IOCMProvider;
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OCP\OCM;
|
||||
|
||||
use OC\OCM\Model\OCMResource;
|
||||
use OCP\OCM\Exceptions\OCMArgumentException;
|
||||
use OCP\OCM\Exceptions\OCMProviderException;
|
||||
|
||||
/**
|
||||
* Model based on the Open Cloud Mesh Discovery API
|
||||
* @link https://github.com/cs3org/OCM-API/
|
||||
* @since 28.0.0
|
||||
*/
|
||||
interface IOCMProvider {
|
||||
/**
|
||||
* enable OCM
|
||||
*
|
||||
* @param bool $enabled
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function setEnabled(bool $enabled): self;
|
||||
|
||||
/**
|
||||
* is set as enabled ?
|
||||
*
|
||||
* @return bool
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function isEnabled(): bool;
|
||||
|
||||
/**
|
||||
* get set API Version
|
||||
*
|
||||
* @param string $apiVersion
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function setApiVersion(string $apiVersion): self;
|
||||
|
||||
/**
|
||||
* returns API version
|
||||
*
|
||||
* @return string
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getApiVersion(): string;
|
||||
|
||||
/**
|
||||
* configure endpoint
|
||||
*
|
||||
* @param string $endPoint
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function setEndPoint(string $endPoint): self;
|
||||
|
||||
/**
|
||||
* get configured endpoint
|
||||
*
|
||||
* @return string
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getEndPoint(): string;
|
||||
|
||||
/**
|
||||
* add a single resource to the object
|
||||
*
|
||||
* @param OCMResource $resource
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function addResourceType(OCMResource $resource): self;
|
||||
|
||||
/**
|
||||
* set resources
|
||||
*
|
||||
* @param OCMResource[] $resourceTypes
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function setResourceTypes(array $resourceTypes): self;
|
||||
|
||||
/**
|
||||
* get all set resources
|
||||
*
|
||||
* @return IOCMResource[]
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getResourceTypes(): array;
|
||||
|
||||
/**
|
||||
* extract a specific string value from the listing of protocols, based on resource-name and protocol-name
|
||||
*
|
||||
* @param string $resourceName
|
||||
* @param string $protocol
|
||||
*
|
||||
* @return string
|
||||
* @throws OCMArgumentException
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function extractProtocolEntry(string $resourceName, string $protocol): string;
|
||||
|
||||
/**
|
||||
* import data from an array
|
||||
*
|
||||
* @param array<string, int|string|bool|array> $data
|
||||
*
|
||||
* @return self
|
||||
* @throws OCMProviderException in case a descent provider cannot be generated from data
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function import(array $data): self;
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.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 OCP\OCM;
|
||||
|
||||
/**
|
||||
* Model based on the Open Cloud Mesh Discovery API
|
||||
*
|
||||
* @link https://github.com/cs3org/OCM-API/
|
||||
* @since 28.0.0
|
||||
*/
|
||||
interface IOCMResource {
|
||||
/**
|
||||
* set name of the resource
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function setName(string $name): self;
|
||||
|
||||
/**
|
||||
* get name of the resource
|
||||
*
|
||||
* @return string
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* set share types
|
||||
*
|
||||
* @param string[] $shareTypes
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function setShareTypes(array $shareTypes): self;
|
||||
|
||||
/**
|
||||
* get share types
|
||||
*
|
||||
* @return string[]
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getShareTypes(): array;
|
||||
|
||||
/**
|
||||
* set available protocols
|
||||
*
|
||||
* @param array<string, string> $protocols
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function setProtocols(array $protocols): self;
|
||||
|
||||
/**
|
||||
* get configured protocols
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function getProtocols(): array;
|
||||
|
||||
/**
|
||||
* import data from an array
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return self
|
||||
* @since 28.0.0
|
||||
*/
|
||||
public function import(array $data): self;
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Bjoern Schiessle <bjoern@schiessle.org>
|
||||
*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
require_once __DIR__ . '/../lib/base.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$server = \OC::$server;
|
||||
|
||||
$isEnabled = $server->getAppManager()->isEnabledForUser('cloud_federation_api');
|
||||
|
||||
if ($isEnabled) {
|
||||
// Make sure the routes are loaded
|
||||
\OC_App::loadApp('cloud_federation_api');
|
||||
$capabilities = new OCA\CloudFederationAPI\Capabilities($server->getURLGenerator());
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($capabilities->getCapabilities()['ocm']);
|
||||
} else {
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 501 Not Implemented", true, 501);
|
||||
exit("501 Not Implemented");
|
||||
}
|
Loading…
Reference in New Issue