Skip to content

Commit

Permalink
ocm controller
Browse files Browse the repository at this point in the history
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
  • Loading branch information
ArtificialOwl committed Jul 26, 2023
1 parent 19e7704 commit 272c067
Show file tree
Hide file tree
Showing 23 changed files with 1,000 additions and 236 deletions.
15 changes: 11 additions & 4 deletions apps/cloud_federation_api/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @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
*
Expand All @@ -27,15 +28,21 @@
'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',
// ]
],
];
46 changes: 25 additions & 21 deletions apps/cloud_federation_api/lib/Capabilities.php
Original file line number Diff line number Diff line change
@@ -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
*
Expand All @@ -23,16 +27,20 @@
*/
namespace OCA\CloudFederationAPI;

use OC\OCM\Model\OCMProvider;
use OC\OCM\Model\OCMResource;
use OCP\Capabilities\ICapability;
use OCP\IURLGenerator;
use OCP\OCM\IOCMDiscoveryService;

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,
private IOCMDiscoveryService $discoveryService
) {
}

/**
Expand All @@ -55,23 +63,19 @@ public function __construct(IURLGenerator $urlGenerator) {
*/
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);
$provider->setEndPoint(substr($url, 0, strrpos($url, '/')));

Check notice

Code scanning / Psalm

PossiblyFalseArgument Note

Argument 3 of substr cannot be false, possibly int|null value expected

$resource = new OCMResource();
$resource->setName('file')
->setShareTypes(['user', 'group'])
->setProtocols(['webdav' => '/public.php/webdav/']);

$provider->setResourceTypes([$resource]);

return ['ocm' => $provider];

Check failure on line 79 in apps/cloud_federation_api/lib/Capabilities.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

InvalidReturnStatement

apps/cloud_federation_api/lib/Capabilities.php:79:10: InvalidReturnStatement: The inferred type 'array{ocm: OC\OCM\Model\OCMProvider}' does not match the declared return type 'array{ocm: array{apiVersion: string, enabled: bool, endPoint: string, resourceTypes: array<array-key, array{name: string, protocols: array{webdav: string}, shareTypes: array<array-key, string>}>}}' for OCA\CloudFederationAPI\Capabilities::getCapabilities (see https://psalm.dev/128)

Check failure

Code scanning / Psalm

InvalidReturnStatement Error

The inferred type 'array{ocm: OC\OCM\Model\OCMProvider}' does not match the declared return type 'array{ocm: array{apiVersion: string, enabled: bool, endPoint: string, resourceTypes: array<array-key, array{name: string, protocols: array{webdav: string}, shareTypes: array<array-key, string>}>}}' for OCA\CloudFederationAPI\Capabilities::getCapabilities
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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>
*
Expand Down Expand Up @@ -56,51 +57,20 @@
*/
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;
}

/**
Expand Down
25 changes: 14 additions & 11 deletions apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @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
Expand All @@ -29,21 +30,19 @@
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) {
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);
}

Expand All @@ -56,6 +55,10 @@ public function run($argument) {
$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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ public function testRemote($remote) {
}

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');
Expand Down
90 changes: 51 additions & 39 deletions apps/files_sharing/lib/External/Storage.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
Expand All @@ -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>
Expand Down Expand Up @@ -36,8 +40,8 @@
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;
Expand All @@ -46,58 +50,66 @@
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
*/
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->extractProtocolUrl('file', 'webdav');
$secure = (parse_url($ocmProvider->getEndPoint(), PHP_URL_SCHEME) === 'https');
$host = parse_url($ocmProvider->getEndPoint(), PHP_URL_HOST);
} catch (OCMProviderException|OCMArgumentException $e) {
$this->logger->notice('exception while retrieving webdav endpoint', ['exception' => $e]);
$webDavEndpoint = '/public.php/webdav';
$secure = true;
$host = parse_url($this->cloudId->getRemote(), PHP_URL_HOST);
}
$secure = $protocol === 'https';
$federatedSharingEndpoints = $discoveryService->discover($this->cloudId->getRemote(), 'FEDERATED_SHARING');
$webDavEndpoint = isset($federatedSharingEndpoints['webdav']) ? $federatedSharingEndpoints['webdav'] : '/public.php/webdav';
$root = rtrim($root, '/') . $webDavEndpoint;

// 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' => $secure,
'host' => $host,
'root' => $webDavEndpoint,
'user' => $options['token'],
'password' => (string)$options['password']
]
);
}

public function getWatcher($path = '', $storage = null) {
Expand Down Expand Up @@ -255,9 +267,9 @@ public function file_exists($path) {
*/
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;
}
Expand Down
1 change: 0 additions & 1 deletion build/files-checker.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
'jest.config.ts',
'lib',
'occ',
'ocm-provider',
'ocs',
'ocs-provider',
'package-lock.json',
Expand Down
Loading

0 comments on commit 272c067

Please sign in to comment.