Signed-off-by: Maxence Lange <maxence@artificial-owl.com>tags/v28.0.0beta1
* @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com> | * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com> | ||||
* | * | ||||
* @author 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 | * @license GNU AGPL version 3 or any later version | ||||
* | * | ||||
'routes' => [ | 'routes' => [ | ||||
[ | [ | ||||
'name' => 'RequestHandler#addShare', | 'name' => 'RequestHandler#addShare', | ||||
'url' => '/ocm/shares', | |||||
'url' => '/shares', | |||||
'verb' => 'POST', | 'verb' => 'POST', | ||||
'root' => '', | |||||
'root' => '/ocm', | |||||
], | ], | ||||
[ | [ | ||||
'name' => 'RequestHandler#receiveNotification', | 'name' => 'RequestHandler#receiveNotification', | ||||
'url' => '/ocm/notifications', | |||||
'url' => '/notifications', | |||||
'verb' => 'POST', | 'verb' => 'POST', | ||||
'root' => '', | |||||
'root' => '/ocm', | |||||
], | ], | ||||
// [ | |||||
// 'name' => 'RequestHandler#inviteAccepted', | |||||
// 'url' => '/invite-accepted', | |||||
// 'verb' => 'POST', | |||||
// 'root' => '/ocm', | |||||
// ] | |||||
], | ], | ||||
]; | ]; |
<?php | <?php | ||||
declare(strict_types=1); | |||||
/** | /** | ||||
* @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org> | * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org> | ||||
* | * | ||||
* @author Bjoern Schiessle <bjoern@schiessle.org> | * @author Bjoern Schiessle <bjoern@schiessle.org> | ||||
* @author Kate Döen <kate.doeen@nextcloud.com> | * @author Kate Döen <kate.doeen@nextcloud.com> | ||||
* @author Maxence Lange <maxence@artificial-owl.com> | |||||
* | * | ||||
* @license GNU AGPL version 3 or any later version | * @license GNU AGPL version 3 or any later version | ||||
* | * | ||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
* | * | ||||
*/ | */ | ||||
namespace OCA\CloudFederationAPI; | namespace OCA\CloudFederationAPI; | ||||
use OC\OCM\Model\OCMProvider; | |||||
use OC\OCM\Model\OCMResource; | |||||
use OCP\Capabilities\ICapability; | use OCP\Capabilities\ICapability; | ||||
use OCP\IURLGenerator; | use OCP\IURLGenerator; | ||||
use OCP\OCM\Exceptions\OCMArgumentException; | |||||
class Capabilities implements ICapability { | 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, | |||||
) { | |||||
} | } | ||||
/** | /** | ||||
* resourceTypes: array{ | * resourceTypes: array{ | ||||
* name: string, | * name: string, | ||||
* shareTypes: string[], | * shareTypes: string[], | ||||
* protocols: array{ | |||||
* webdav: string, | |||||
* }, | |||||
* }[], | |||||
* }, | |||||
* protocols: array<string, string> | |||||
* }[], | |||||
* }, | |||||
* } | * } | ||||
* @throws OCMArgumentException | |||||
*/ | */ | ||||
public function getCapabilities() { | public function getCapabilities() { | ||||
$url = $this->urlGenerator->linkToRouteAbsolute('cloud_federation_api.requesthandlercontroller.addShare'); | $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()]; | |||||
} | } | ||||
} | } |
* | * | ||||
* @author Bjoern Schiessle <bjoern@schiessle.org> | * @author Bjoern Schiessle <bjoern@schiessle.org> | ||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at> | * @author Christoph Wurst <christoph@winzerhof-wurst.at> | ||||
* @author Maxence Lange <maxence@artificial-owl.com> | |||||
* @author Roeland Jago Douma <roeland@famdouma.nl> | * @author Roeland Jago Douma <roeland@famdouma.nl> | ||||
* @author Kate Döen <kate.doeen@nextcloud.com> | * @author Kate Döen <kate.doeen@nextcloud.com> | ||||
* | * | ||||
* @psalm-import-type CloudFederationApiError from ResponseDefinitions | * @psalm-import-type CloudFederationApiError from ResponseDefinitions | ||||
*/ | */ | ||||
class RequestHandlerController extends Controller { | 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); | 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; | |||||
} | } | ||||
/** | /** | ||||
* 501: Share type or the resource type is not supported | * 501: Share type or the resource type is not supported | ||||
*/ | */ | ||||
public function addShare($shareWith, $name, $description, $providerId, $owner, $ownerDisplayName, $sharedBy, $sharedByDisplayName, $protocol, $shareType, $resourceType) { | public function addShare($shareWith, $name, $description, $providerId, $owner, $ownerDisplayName, $sharedBy, $sharedByDisplayName, $protocol, $shareType, $resourceType) { | ||||
// check if all required parameters are set | // check if all required parameters are set | ||||
if ($shareWith === null || | if ($shareWith === null || | ||||
$name === null || | $name === null || | ||||
* 501: The resource type is not supported | * 501: The resource type is not supported | ||||
*/ | */ | ||||
public function receiveNotification($notificationType, $resourceType, $providerId, ?array $notification) { | public function receiveNotification($notificationType, $resourceType, $providerId, ?array $notification) { | ||||
// check if all required parameters are set | // check if all required parameters are set | ||||
if ($notificationType === null || | if ($notificationType === null || | ||||
$resourceType === null || | $resourceType === null || | ||||
); | ); | ||||
} | } | ||||
return new JSONResponse($result,Http::STATUS_CREATED); | |||||
return new JSONResponse($result, Http::STATUS_CREATED); | |||||
} | } | ||||
/** | /** |
}, | }, | ||||
"protocols": { | "protocols": { | ||||
"type": "object", | "type": "object", | ||||
"required": [ | |||||
"webdav" | |||||
], | |||||
"properties": { | |||||
"webdav": { | |||||
"type": "string" | |||||
} | |||||
"additionalProperties": { | |||||
"type": "string" | |||||
} | } | ||||
} | } | ||||
} | } |
* @copyright 2018, Roeland Jago Douma <roeland@famdouma.nl> | * @copyright 2018, Roeland Jago Douma <roeland@famdouma.nl> | ||||
* | * | ||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at> | * @author Christoph Wurst <christoph@winzerhof-wurst.at> | ||||
* @author Maxence Lange <maxence@artificial-owl.com> | |||||
* @author Roeland Jago Douma <roeland@famdouma.nl> | * @author Roeland Jago Douma <roeland@famdouma.nl> | ||||
* | * | ||||
* @license GNU AGPL version 3 or any later version | * @license GNU AGPL version 3 or any later version | ||||
use OCP\AppFramework\Utility\ITimeFactory; | use OCP\AppFramework\Utility\ITimeFactory; | ||||
use OCP\BackgroundJob\TimedJob; | use OCP\BackgroundJob\TimedJob; | ||||
use OCP\IDBConnection; | use OCP\IDBConnection; | ||||
use OCP\OCM\Exceptions\OCMProviderException; | |||||
use OCP\OCM\IOCMDiscoveryService; | |||||
use OCP\OCS\IDiscoveryService; | use OCP\OCS\IDiscoveryService; | ||||
class FederatedSharesDiscoverJob extends TimedJob { | class FederatedSharesDiscoverJob extends TimedJob { | ||||
/** @var IDBConnection */ | |||||
private $connection; | |||||
/** @var IDiscoveryService */ | |||||
private $discoveryService; | |||||
public function __construct(ITimeFactory $time, | |||||
IDBConnection $connection, | |||||
IDiscoveryService $discoveryService) { | |||||
parent::__construct($time); | |||||
$this->connection = $connection; | |||||
$this->discoveryService = $discoveryService; | |||||
public function __construct( | |||||
ITimeFactory $time, | |||||
private IDBConnection $connection, | |||||
private IDiscoveryService $discoveryService, | |||||
private IOCMDiscoveryService $ocmDiscoveryService | |||||
) { | |||||
parent::__construct($time); | |||||
$this->setInterval(86400); | $this->setInterval(86400); | ||||
} | } | ||||
$result = $qb->execute(); | $result = $qb->execute(); | ||||
while ($row = $result->fetch()) { | while ($row = $result->fetch()) { | ||||
$this->discoveryService->discover($row['remote'], 'FEDERATED_SHARING', true); | $this->discoveryService->discover($row['remote'], 'FEDERATED_SHARING', true); | ||||
try { | |||||
$this->ocmDiscoveryService->discover($row['remote'], true); | |||||
} catch (OCMProviderException $e) { | |||||
} | |||||
} | } | ||||
$result->closeCursor(); | $result->closeCursor(); | ||||
} | } |
} | } | ||||
if ( | 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) | $this->testUrl('https://' . $remote . '/status.php', true) | ||||
) { | ) { | ||||
return new DataResponse('https'); | return new DataResponse('https'); | ||||
} elseif ( | } 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) | $this->testUrl('http://' . $remote . '/status.php', true) | ||||
) { | ) { | ||||
return new DataResponse('http'); | return new DataResponse('http'); |
<?php | <?php | ||||
declare(strict_types=1); | |||||
/** | /** | ||||
* @copyright Copyright (c) 2016, ownCloud, Inc. | * @copyright Copyright (c) 2016, ownCloud, Inc. | ||||
* | * | ||||
* @author Daniel Kesselberg <mail@danielkesselberg.de> | * @author Daniel Kesselberg <mail@danielkesselberg.de> | ||||
* @author Joas Schilling <coding@schilljs.com> | * @author Joas Schilling <coding@schilljs.com> | ||||
* @author Lukas Reschke <lukas@statuscode.ch> | * @author Lukas Reschke <lukas@statuscode.ch> | ||||
* @author Maxence Lange <maxence@artificial-owl.com> | |||||
* @author Morris Jobke <hey@morrisjobke.de> | * @author Morris Jobke <hey@morrisjobke.de> | ||||
* @author Robin Appelman <robin@icewind.nl> | * @author Robin Appelman <robin@icewind.nl> | ||||
* @author Roeland Jago Douma <roeland@famdouma.nl> | * @author Roeland Jago Douma <roeland@famdouma.nl> | ||||
use GuzzleHttp\Exception\RequestException; | use GuzzleHttp\Exception\RequestException; | ||||
use OC\Files\Storage\DAV; | use OC\Files\Storage\DAV; | ||||
use OC\ForbiddenException; | use OC\ForbiddenException; | ||||
use OCA\Files_Sharing\ISharedStorage; | |||||
use OCA\Files_Sharing\External\Manager as ExternalShareManager; | use OCA\Files_Sharing\External\Manager as ExternalShareManager; | ||||
use OCA\Files_Sharing\ISharedStorage; | |||||
use OCP\AppFramework\Http; | use OCP\AppFramework\Http; | ||||
use OCP\Constants; | use OCP\Constants; | ||||
use OCP\Federation\ICloudId; | use OCP\Federation\ICloudId; | ||||
use OCP\Files\Storage\IReliableEtagStorage; | use OCP\Files\Storage\IReliableEtagStorage; | ||||
use OCP\Files\StorageInvalidException; | use OCP\Files\StorageInvalidException; | ||||
use OCP\Files\StorageNotAvailableException; | use OCP\Files\StorageNotAvailableException; | ||||
use OCP\Http\Client\LocalServerException; | |||||
use OCP\Http\Client\IClientService; | 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 { | 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 | * @param array{HttpClientService: IClientService, manager: ExternalShareManager, cloudId: ICloudId, mountpoint: string, token: string, password: ?string}|array $options | ||||
public function __construct($options) { | public function __construct($options) { | ||||
$this->memcacheFactory = \OC::$server->getMemCacheFactory(); | $this->memcacheFactory = \OC::$server->getMemCacheFactory(); | ||||
$this->httpClient = $options['HttpClientService']; | $this->httpClient = $options['HttpClientService']; | ||||
$this->manager = $options['manager']; | $this->manager = $options['manager']; | ||||
$this->cloudId = $options['cloudId']; | $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(); | |||||
} | |||||
$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; | |||||
} | } | ||||
$secure = $protocol === 'https'; | |||||
$federatedSharingEndpoints = $discoveryService->discover($this->cloudId->getRemote(), 'FEDERATED_SHARING'); | |||||
$webDavEndpoint = isset($federatedSharingEndpoints['webdav']) ? $federatedSharingEndpoints['webdav'] : '/public.php/webdav'; | |||||
$root = rtrim($root, '/') . $webDavEndpoint; | |||||
$this->mountPoint = $options['mountpoint']; | $this->mountPoint = $options['mountpoint']; | ||||
$this->token = $options['token']; | $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) { | public function getWatcher($path = '', $storage = null) { | ||||
*/ | */ | ||||
protected function testRemote(): bool { | protected function testRemote(): bool { | ||||
try { | 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) { | } catch (\Exception $e) { | ||||
return false; | return false; | ||||
} | } |
namespace OCA\Files_Sharing\Tests; | namespace OCA\Files_Sharing\Tests; | ||||
use OC\Federation\CloudId; | use OC\Federation\CloudId; | ||||
use OCA\Files_Sharing\External\Manager as ExternalShareManager; | |||||
use OCP\Http\Client\IClient; | use OCP\Http\Client\IClient; | ||||
use OCP\Http\Client\IClientService; | use OCP\Http\Client\IClientService; | ||||
use OCP\Http\Client\IResponse; | use OCP\Http\Client\IResponse; | ||||
private function getTestStorage($uri) { | private function getTestStorage($uri) { | ||||
$certificateManager = \OC::$server->getCertificateManager(); | $certificateManager = \OC::$server->getCertificateManager(); | ||||
$httpClientService = $this->createMock(IClientService::class); | $httpClientService = $this->createMock(IClientService::class); | ||||
$manager = $this->createMock(ExternalShareManager::class); | |||||
$client = $this->createMock(IClient::class); | $client = $this->createMock(IClient::class); | ||||
$response = $this->createMock(IResponse::class); | $response = $this->createMock(IResponse::class); | ||||
$client | $client | ||||
'mountpoint' => 'remoteshare', | 'mountpoint' => 'remoteshare', | ||||
'token' => 'abcdef', | 'token' => 'abcdef', | ||||
'password' => '', | 'password' => '', | ||||
'manager' => null, | |||||
'manager' => $manager, | |||||
'certificateManager' => $certificateManager, | 'certificateManager' => $certificateManager, | ||||
'HttpClientService' => $httpClientService, | 'HttpClientService' => $httpClientService, | ||||
] | ] |
'jest.config.ts', | 'jest.config.ts', | ||||
'lib', | 'lib', | ||||
'occ', | 'occ', | ||||
'ocm-provider', | |||||
'ocs', | 'ocs', | ||||
'ocs-provider', | 'ocs-provider', | ||||
'package-lock.json', | 'package-lock.json', |
<code>IEventListener</code> | <code>IEventListener</code> | ||||
</MissingTemplateParam> | </MissingTemplateParam> | ||||
</file> | </file> | ||||
<file src="apps/cloud_federation_api/lib/Capabilities.php"> | |||||
<LessSpecificImplementedReturnType> | |||||
<code>array</code> | |||||
</LessSpecificImplementedReturnType> | |||||
</file> | |||||
<file src="apps/comments/lib/Listener/CommentsEntityEventListener.php"> | <file src="apps/comments/lib/Listener/CommentsEntityEventListener.php"> | ||||
<MissingTemplateParam> | <MissingTemplateParam> | ||||
<code>IEventListener</code> | <code>IEventListener</code> |
<?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 | |||||
); | |||||
} | |||||
} | |||||
} |
{ | { | ||||
"name": "guest_avatar", | "name": "guest_avatar", | ||||
"description": "This controller handles guest avatar requests." | "description": "This controller handles guest avatar requests." | ||||
}, | |||||
{ | |||||
"name": "ocm", | |||||
"description": "Controller about the endpoint /ocm-provider/" | |||||
} | } | ||||
] | ] | ||||
} | } |
* @author John Molakvoæ <skjnldsv@protonmail.com> | * @author John Molakvoæ <skjnldsv@protonmail.com> | ||||
* @author Julius Härtl <jus@bitgrid.net> | * @author Julius Härtl <jus@bitgrid.net> | ||||
* @author Lukas Reschke <lukas@statuscode.ch> | * @author Lukas Reschke <lukas@statuscode.ch> | ||||
* @author Maxence Lange <maxence@artificial-owl.com> | |||||
* @author Michael Weimann <mail@michael-weimann.eu> | * @author Michael Weimann <mail@michael-weimann.eu> | ||||
* @author Roeland Jago Douma <roeland@famdouma.nl> | * @author Roeland Jago Douma <roeland@famdouma.nl> | ||||
* @author Thomas Müller <thomas.mueller@tmit.eu> | * @author Thomas Müller <thomas.mueller@tmit.eu> | ||||
// Well known requests https://tools.ietf.org/html/rfc5785 | // Well known requests https://tools.ietf.org/html/rfc5785 | ||||
['name' => 'WellKnown#handle', 'url' => '.well-known/{service}'], | ['name' => 'WellKnown#handle', 'url' => '.well-known/{service}'], | ||||
// OCM Provider requests https://github.com/cs3org/OCM-API | |||||
['name' => 'OCM#discovery', 'url' => '/ocm-provider/'], | |||||
// Unsupported browser | // Unsupported browser | ||||
['name' => 'UnsupportedBrowser#index', 'url' => 'unsupported'], | ['name' => 'UnsupportedBrowser#index', 'url' => 'unsupported'], | ||||
], | ], |
'OCP\\Notification\\IManager' => $baseDir . '/lib/public/Notification/IManager.php', | 'OCP\\Notification\\IManager' => $baseDir . '/lib/public/Notification/IManager.php', | ||||
'OCP\\Notification\\INotification' => $baseDir . '/lib/public/Notification/INotification.php', | 'OCP\\Notification\\INotification' => $baseDir . '/lib/public/Notification/INotification.php', | ||||
'OCP\\Notification\\INotifier' => $baseDir . '/lib/public/Notification/INotifier.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\\OCS\\IDiscoveryService' => $baseDir . '/lib/public/OCS/IDiscoveryService.php', | ||||
'OCP\\PreConditionNotMetException' => $baseDir . '/lib/public/PreConditionNotMetException.php', | 'OCP\\PreConditionNotMetException' => $baseDir . '/lib/public/PreConditionNotMetException.php', | ||||
'OCP\\Preview\\BeforePreviewFetchedEvent' => $baseDir . '/lib/public/Preview/BeforePreviewFetchedEvent.php', | 'OCP\\Preview\\BeforePreviewFetchedEvent' => $baseDir . '/lib/public/Preview/BeforePreviewFetchedEvent.php', | ||||
'OC\\Core\\Controller\\LostController' => $baseDir . '/core/Controller/LostController.php', | 'OC\\Core\\Controller\\LostController' => $baseDir . '/core/Controller/LostController.php', | ||||
'OC\\Core\\Controller\\NavigationController' => $baseDir . '/core/Controller/NavigationController.php', | 'OC\\Core\\Controller\\NavigationController' => $baseDir . '/core/Controller/NavigationController.php', | ||||
'OC\\Core\\Controller\\OCJSController' => $baseDir . '/core/Controller/OCJSController.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\\OCSController' => $baseDir . '/core/Controller/OCSController.php', | ||||
'OC\\Core\\Controller\\PreviewController' => $baseDir . '/core/Controller/PreviewController.php', | 'OC\\Core\\Controller\\PreviewController' => $baseDir . '/core/Controller/PreviewController.php', | ||||
'OC\\Core\\Controller\\ProfileApiController' => $baseDir . '/core/Controller/ProfileApiController.php', | 'OC\\Core\\Controller\\ProfileApiController' => $baseDir . '/core/Controller/ProfileApiController.php', | ||||
'OC\\Notification\\Action' => $baseDir . '/lib/private/Notification/Action.php', | 'OC\\Notification\\Action' => $baseDir . '/lib/private/Notification/Action.php', | ||||
'OC\\Notification\\Manager' => $baseDir . '/lib/private/Notification/Manager.php', | 'OC\\Notification\\Manager' => $baseDir . '/lib/private/Notification/Manager.php', | ||||
'OC\\Notification\\Notification' => $baseDir . '/lib/private/Notification/Notification.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\\CoreCapabilities' => $baseDir . '/lib/private/OCS/CoreCapabilities.php', | ||||
'OC\\OCS\\DiscoveryService' => $baseDir . '/lib/private/OCS/DiscoveryService.php', | 'OC\\OCS\\DiscoveryService' => $baseDir . '/lib/private/OCS/DiscoveryService.php', | ||||
'OC\\OCS\\Exception' => $baseDir . '/lib/private/OCS/Exception.php', | 'OC\\OCS\\Exception' => $baseDir . '/lib/private/OCS/Exception.php', |
'OCP\\Notification\\IManager' => __DIR__ . '/../../..' . '/lib/public/Notification/IManager.php', | 'OCP\\Notification\\IManager' => __DIR__ . '/../../..' . '/lib/public/Notification/IManager.php', | ||||
'OCP\\Notification\\INotification' => __DIR__ . '/../../..' . '/lib/public/Notification/INotification.php', | 'OCP\\Notification\\INotification' => __DIR__ . '/../../..' . '/lib/public/Notification/INotification.php', | ||||
'OCP\\Notification\\INotifier' => __DIR__ . '/../../..' . '/lib/public/Notification/INotifier.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\\OCS\\IDiscoveryService' => __DIR__ . '/../../..' . '/lib/public/OCS/IDiscoveryService.php', | ||||
'OCP\\PreConditionNotMetException' => __DIR__ . '/../../..' . '/lib/public/PreConditionNotMetException.php', | 'OCP\\PreConditionNotMetException' => __DIR__ . '/../../..' . '/lib/public/PreConditionNotMetException.php', | ||||
'OCP\\Preview\\BeforePreviewFetchedEvent' => __DIR__ . '/../../..' . '/lib/public/Preview/BeforePreviewFetchedEvent.php', | 'OCP\\Preview\\BeforePreviewFetchedEvent' => __DIR__ . '/../../..' . '/lib/public/Preview/BeforePreviewFetchedEvent.php', | ||||
'OC\\Core\\Controller\\LostController' => __DIR__ . '/../../..' . '/core/Controller/LostController.php', | 'OC\\Core\\Controller\\LostController' => __DIR__ . '/../../..' . '/core/Controller/LostController.php', | ||||
'OC\\Core\\Controller\\NavigationController' => __DIR__ . '/../../..' . '/core/Controller/NavigationController.php', | 'OC\\Core\\Controller\\NavigationController' => __DIR__ . '/../../..' . '/core/Controller/NavigationController.php', | ||||
'OC\\Core\\Controller\\OCJSController' => __DIR__ . '/../../..' . '/core/Controller/OCJSController.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\\OCSController' => __DIR__ . '/../../..' . '/core/Controller/OCSController.php', | ||||
'OC\\Core\\Controller\\PreviewController' => __DIR__ . '/../../..' . '/core/Controller/PreviewController.php', | 'OC\\Core\\Controller\\PreviewController' => __DIR__ . '/../../..' . '/core/Controller/PreviewController.php', | ||||
'OC\\Core\\Controller\\ProfileApiController' => __DIR__ . '/../../..' . '/core/Controller/ProfileApiController.php', | 'OC\\Core\\Controller\\ProfileApiController' => __DIR__ . '/../../..' . '/core/Controller/ProfileApiController.php', | ||||
'OC\\Notification\\Action' => __DIR__ . '/../../..' . '/lib/private/Notification/Action.php', | 'OC\\Notification\\Action' => __DIR__ . '/../../..' . '/lib/private/Notification/Action.php', | ||||
'OC\\Notification\\Manager' => __DIR__ . '/../../..' . '/lib/private/Notification/Manager.php', | 'OC\\Notification\\Manager' => __DIR__ . '/../../..' . '/lib/private/Notification/Manager.php', | ||||
'OC\\Notification\\Notification' => __DIR__ . '/../../..' . '/lib/private/Notification/Notification.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\\CoreCapabilities' => __DIR__ . '/../../..' . '/lib/private/OCS/CoreCapabilities.php', | ||||
'OC\\OCS\\DiscoveryService' => __DIR__ . '/../../..' . '/lib/private/OCS/DiscoveryService.php', | 'OC\\OCS\\DiscoveryService' => __DIR__ . '/../../..' . '/lib/private/OCS/DiscoveryService.php', | ||||
'OC\\OCS\\Exception' => __DIR__ . '/../../..' . '/lib/private/OCS/Exception.php', | 'OC\\OCS\\Exception' => __DIR__ . '/../../..' . '/lib/private/OCS/Exception.php', |
<?php | <?php | ||||
declare(strict_types=1); | |||||
/** | /** | ||||
* @copyright Copyright (c) 2018 Bjoern Schiessle <bjoern@schiessle.org> | * @copyright Copyright (c) 2018 Bjoern Schiessle <bjoern@schiessle.org> | ||||
* | * | ||||
* @author Bjoern Schiessle <bjoern@schiessle.org> | * @author Bjoern Schiessle <bjoern@schiessle.org> | ||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at> | * @author Christoph Wurst <christoph@winzerhof-wurst.at> | ||||
* @author Maxence Lange <maxence@artificial-owl.com> | |||||
* | * | ||||
* @license GNU AGPL version 3 or any later version | * @license GNU AGPL version 3 or any later version | ||||
* | * | ||||
use OCP\Federation\ICloudFederationShare; | use OCP\Federation\ICloudFederationShare; | ||||
use OCP\Federation\ICloudIdManager; | use OCP\Federation\ICloudIdManager; | ||||
use OCP\Http\Client\IClientService; | use OCP\Http\Client\IClientService; | ||||
use OCP\IConfig; | |||||
use OCP\OCM\Exceptions\OCMProviderException; | |||||
use OCP\OCM\IOCMDiscoveryService; | |||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
/** | /** | ||||
*/ | */ | ||||
class CloudFederationProviderManager implements ICloudFederationProviderManager { | class CloudFederationProviderManager implements ICloudFederationProviderManager { | ||||
/** @var array list of available cloud federation providers */ | /** @var array list of available cloud federation providers */ | ||||
private $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; | |||||
private array $cloudFederationProvider = []; | |||||
public function __construct( | |||||
private IConfig $config, | |||||
private IAppManager $appManager, | |||||
private IClientService $httpClientService, | |||||
private ICloudIdManager $cloudIdManager, | |||||
private IOCMDiscoveryService $discoveryService, | |||||
private LoggerInterface $logger | |||||
) { | |||||
} | } | ||||
public function sendShare(ICloudFederationShare $share) { | public function sendShare(ICloudFederationShare $share) { | ||||
$cloudID = $this->cloudIdManager->resolveCloudId($share->getShareWith()); | $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; | return false; | ||||
} | } | ||||
$client = $this->httpClientService->newClient(); | $client = $this->httpClientService->newClient(); | ||||
try { | try { | ||||
$response = $client->post($ocmEndPoint . '/shares', [ | |||||
$response = $client->post($ocmProvider->getEndPoint() . '/shares', [ | |||||
'body' => json_encode($share->getShare()), | 'body' => json_encode($share->getShare()), | ||||
'headers' => ['content-type' => 'application/json'], | 'headers' => ['content-type' => 'application/json'], | ||||
'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates', false), | |||||
'timeout' => 10, | 'timeout' => 10, | ||||
'connect_timeout' => 10, | 'connect_timeout' => 10, | ||||
]); | ]); | ||||
* @return array|false | * @return array|false | ||||
*/ | */ | ||||
public function sendNotification($url, ICloudFederationNotification $notification) { | public function sendNotification($url, ICloudFederationNotification $notification) { | ||||
$ocmEndPoint = $this->getOCMEndPoint($url); | |||||
if (empty($ocmEndPoint)) { | |||||
try { | |||||
$ocmProvider = $this->discoveryService->discover($url); | |||||
} catch (OCMProviderException $e) { | |||||
return false; | return false; | ||||
} | } | ||||
$client = $this->httpClientService->newClient(); | $client = $this->httpClientService->newClient(); | ||||
try { | try { | ||||
$response = $client->post($ocmEndPoint . '/notifications', [ | |||||
$response = $client->post($ocmProvider->getEndPoint() . '/notifications', [ | |||||
'body' => json_encode($notification->getMessage()), | 'body' => json_encode($notification->getMessage()), | ||||
'headers' => ['content-type' => 'application/json'], | 'headers' => ['content-type' => 'application/json'], | ||||
'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates', false), | |||||
'timeout' => 10, | 'timeout' => 10, | ||||
'connect_timeout' => 10, | 'connect_timeout' => 10, | ||||
]); | ]); | ||||
public function isReady() { | public function isReady() { | ||||
return $this->appManager->isEnabledForUser('cloud_federation_api'); | 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 ''; | |||||
} | |||||
} | } |
<?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 | |||||
]; | |||||
} | |||||
} |
<?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() | |||||
]; | |||||
} | |||||
} |
<?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)); | |||||
} | |||||
} |
use OC\Metadata\IMetadataManager; | use OC\Metadata\IMetadataManager; | ||||
use OC\Metadata\MetadataManager; | use OC\Metadata\MetadataManager; | ||||
use OC\Notification\Manager; | use OC\Notification\Manager; | ||||
use OC\OCM\OCMDiscoveryService; | |||||
use OC\OCS\DiscoveryService; | use OC\OCS\DiscoveryService; | ||||
use OC\Preview\GeneratorHelper; | use OC\Preview\GeneratorHelper; | ||||
use OC\Preview\IMagickSupport; | use OC\Preview\IMagickSupport; | ||||
use OCP\Lockdown\ILockdownManager; | use OCP\Lockdown\ILockdownManager; | ||||
use OCP\Log\ILogFactory; | use OCP\Log\ILogFactory; | ||||
use OCP\Mail\IMailer; | use OCP\Mail\IMailer; | ||||
use OCP\OCM\IOCMDiscoveryService; | |||||
use OCP\Remote\Api\IApiFactory; | use OCP\Remote\Api\IApiFactory; | ||||
use OCP\Remote\IInstanceFactory; | use OCP\Remote\IInstanceFactory; | ||||
use OCP\RichObjectStrings\IValidator; | use OCP\RichObjectStrings\IValidator; | ||||
$c->get(IClientService::class) | $c->get(IClientService::class) | ||||
); | ); | ||||
}); | }); | ||||
$this->registerAlias(IOCMDiscoveryService::class, OCMDiscoveryService::class); | |||||
$this->registerService(ICloudIdManager::class, function (ContainerInterface $c) { | $this->registerService(ICloudIdManager::class, function (ContainerInterface $c) { | ||||
return new CloudIdManager( | return new CloudIdManager( | ||||
$this->registerService(ICloudFederationProviderManager::class, function (ContainerInterface $c) { | $this->registerService(ICloudFederationProviderManager::class, function (ContainerInterface $c) { | ||||
return new CloudFederationProviderManager( | return new CloudFederationProviderManager( | ||||
$c->get(\OCP\IConfig::class), | |||||
$c->get(IAppManager::class), | $c->get(IAppManager::class), | ||||
$c->get(IClientService::class), | $c->get(IClientService::class), | ||||
$c->get(ICloudIdManager::class), | $c->get(ICloudIdManager::class), | ||||
$c->get(IOCMDiscoveryService::class), | |||||
$c->get(LoggerInterface::class) | $c->get(LoggerInterface::class) | ||||
); | ); | ||||
}); | }); |
<?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 { | |||||
} |
<?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 { | |||||
} |
<?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; | |||||
} |
<?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; | |||||
} |
<?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; | |||||
} |
<?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"); | |||||
} |
<directory name="apps/workflowengine"/> | <directory name="apps/workflowengine"/> | ||||
<directory name="core"/> | <directory name="core"/> | ||||
<directory name="lib"/> | <directory name="lib"/> | ||||
<directory name="ocm-provider"/> | |||||
<directory name="ocs"/> | <directory name="ocs"/> | ||||
<directory name="ocs-provider"/> | <directory name="ocs-provider"/> | ||||
<file name="index.php"/> | <file name="index.php"/> |