diff options
Diffstat (limited to 'apps')
20 files changed, 208 insertions, 344 deletions
diff --git a/apps/cloud_federation_api/appinfo/routes.php b/apps/cloud_federation_api/appinfo/routes.php index d70b06f821c..966ff2ce3a1 100644 --- a/apps/cloud_federation_api/appinfo/routes.php +++ b/apps/cloud_federation_api/appinfo/routes.php @@ -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', +// ] ], ]; diff --git a/apps/cloud_federation_api/lib/Capabilities.php b/apps/cloud_federation_api/lib/Capabilities.php index f1398661ebe..1682effb145 100644 --- a/apps/cloud_federation_api/lib/Capabilities.php +++ b/apps/cloud_federation_api/lib/Capabilities.php @@ -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()]; } } diff --git a/apps/cloud_federation_api/lib/Controller/RequestHandlerController.php b/apps/cloud_federation_api/lib/Controller/RequestHandlerController.php index 416dca67160..a10dadbbdce 100644 --- a/apps/cloud_federation_api/lib/Controller/RequestHandlerController.php +++ b/apps/cloud_federation_api/lib/Controller/RequestHandlerController.php @@ -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); } /** diff --git a/apps/cloud_federation_api/openapi.json b/apps/cloud_federation_api/openapi.json index 55263e19f29..ca20c31d6d9 100644 --- a/apps/cloud_federation_api/openapi.json +++ b/apps/cloud_federation_api/openapi.json @@ -76,13 +76,8 @@ }, "protocols": { "type": "object", - "required": [ - "webdav" - ], - "properties": { - "webdav": { - "type": "string" - } + "additionalProperties": { + "type": "string" } } } diff --git a/apps/dav/lib/Command/CreateAddressBook.php b/apps/dav/lib/Command/CreateAddressBook.php index 3d56d95868d..9dfc539a25d 100644 --- a/apps/dav/lib/Command/CreateAddressBook.php +++ b/apps/dav/lib/Command/CreateAddressBook.php @@ -32,26 +32,14 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class CreateAddressBook extends Command { - - /** @var IUserManager */ - private $userManager; - - /** @var CardDavBackend */ - private $cardDavBackend; - - /** - * @param IUserManager $userManager - * @param CardDavBackend $cardDavBackend - */ - public function __construct(IUserManager $userManager, - CardDavBackend $cardDavBackend + public function __construct( + private IUserManager $userManager, + private CardDavBackend $cardDavBackend, ) { parent::__construct(); - $this->userManager = $userManager; - $this->cardDavBackend = $cardDavBackend; } - protected function configure() { + protected function configure(): void { $this ->setName('dav:create-addressbook') ->setDescription('Create a dav addressbook') @@ -71,6 +59,6 @@ class CreateAddressBook extends Command { $name = $input->getArgument('name'); $this->cardDavBackend->createAddressBook("principals/users/$user", $name, []); - return 0; + return self::SUCCESS; } } diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php index 08f937dff9d..d571f113177 100644 --- a/apps/dav/lib/Command/CreateCalendar.php +++ b/apps/dav/lib/Command/CreateCalendar.php @@ -42,29 +42,15 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class CreateCalendar extends Command { - - /** @var IUserManager */ - protected $userManager; - - /** @var IGroupManager $groupManager */ - private $groupManager; - - /** @var \OCP\IDBConnection */ - protected $dbConnection; - - /** - * @param IUserManager $userManager - * @param IGroupManager $groupManager - * @param IDBConnection $dbConnection - */ - public function __construct(IUserManager $userManager, IGroupManager $groupManager, IDBConnection $dbConnection) { + public function __construct( + protected IUserManager $userManager, + private IGroupManager $groupManager, + protected IDBConnection $dbConnection, + ) { parent::__construct(); - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->dbConnection = $dbConnection; } - protected function configure() { + protected function configure(): void { $this ->setName('dav:create-calendar') ->setDescription('Create a dav calendar') @@ -110,6 +96,6 @@ class CreateCalendar extends Command { $config ); $caldav->createCalendar("principals/users/$user", $name, []); - return 0; + return self::SUCCESS; } } diff --git a/apps/dav/lib/Command/DeleteCalendar.php b/apps/dav/lib/Command/DeleteCalendar.php index dd5f11c740f..f9caa142757 100644 --- a/apps/dav/lib/Command/DeleteCalendar.php +++ b/apps/dav/lib/Command/DeleteCalendar.php @@ -38,40 +38,14 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class DeleteCalendar extends Command { - /** @var CalDavBackend */ - private $calDav; - - /** @var IConfig */ - private $config; - - /** @var IL10N */ - private $l10n; - - /** @var IUserManager */ - private $userManager; - - /** @var LoggerInterface */ - private $logger; - - /** - * @param CalDavBackend $calDav - * @param IConfig $config - * @param IL10N $l10n - * @param IUserManager $userManager - */ public function __construct( - CalDavBackend $calDav, - IConfig $config, - IL10N $l10n, - IUserManager $userManager, - LoggerInterface $logger + private CalDavBackend $calDav, + private IConfig $config, + private IL10N $l10n, + private IUserManager $userManager, + private LoggerInterface $logger, ) { parent::__construct(); - $this->calDav = $calDav; - $this->config = $config; - $this->l10n = $l10n; - $this->userManager = $userManager; - $this->logger = $logger; } protected function configure(): void { @@ -140,6 +114,6 @@ class DeleteCalendar extends Command { $calendar->delete(); - return 0; + return self::SUCCESS; } } diff --git a/apps/dav/lib/Command/ListCalendars.php b/apps/dav/lib/Command/ListCalendars.php index 35581c2d4b2..901d2822656 100644 --- a/apps/dav/lib/Command/ListCalendars.php +++ b/apps/dav/lib/Command/ListCalendars.php @@ -35,24 +35,14 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class ListCalendars extends Command { - - /** @var IUserManager */ - protected $userManager; - - /** @var CalDavBackend */ - private $caldav; - - /** - * @param IUserManager $userManager - * @param CalDavBackend $caldav - */ - public function __construct(IUserManager $userManager, CalDavBackend $caldav) { + public function __construct( + protected IUserManager $userManager, + private CalDavBackend $caldav, + ) { parent::__construct(); - $this->userManager = $userManager; - $this->caldav = $caldav; } - protected function configure() { + protected function configure(): void { $this ->setName('dav:list-calendars') ->setDescription('List all calendars of a user') @@ -100,6 +90,6 @@ class ListCalendars extends Command { } else { $output->writeln("<info>User <$user> has no calendars</info>"); } - return 0; + return self::SUCCESS; } } diff --git a/apps/dav/lib/Command/MoveCalendar.php b/apps/dav/lib/Command/MoveCalendar.php index 9272b20b10d..a3045797ff4 100644 --- a/apps/dav/lib/Command/MoveCalendar.php +++ b/apps/dav/lib/Command/MoveCalendar.php @@ -42,37 +42,23 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; class MoveCalendar extends Command { - private IUserManager $userManager; - private IGroupManager $groupManager; - private IShareManager $shareManager; - private IConfig $config; - private IL10N $l10n; private ?SymfonyStyle $io = null; - private CalDavBackend $calDav; - private LoggerInterface $logger; public const URI_USERS = 'principals/users/'; public function __construct( - IUserManager $userManager, - IGroupManager $groupManager, - IShareManager $shareManager, - IConfig $config, - IL10N $l10n, - CalDavBackend $calDav, - LoggerInterface $logger + private IUserManager $userManager, + private IGroupManager $groupManager, + private IShareManager $shareManager, + private IConfig $config, + private IL10N $l10n, + private CalDavBackend $calDav, + private LoggerInterface $logger, ) { parent::__construct(); - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->shareManager = $shareManager; - $this->config = $config; - $this->l10n = $l10n; - $this->calDav = $calDav; - $this->logger = $logger; } - protected function configure() { + protected function configure(): void { $this ->setName('dav:move-calendar') ->setDescription('Move a calendar from an user to another') @@ -140,15 +126,11 @@ class MoveCalendar extends Command { $this->calDav->moveCalendar($name, self::URI_USERS . $userOrigin, self::URI_USERS . $userDestination, $newName); $this->io->success("Calendar <$name> was moved from user <$userOrigin> to <$userDestination>" . ($newName ? " as <$newName>" : '')); - return 0; + return self::SUCCESS; } /** * Check if the calendar exists for user - * - * @param string $userDestination - * @param string $name - * @return bool */ protected function calendarExists(string $userDestination, string $name): bool { return null !== $this->calDav->getCalendarByUri(self::URI_USERS . $userDestination, $name); @@ -156,11 +138,7 @@ class MoveCalendar extends Command { /** * Try to find a suitable new calendar name that - * doesn't exists for the provided user - * - * @param string $userDestination - * @param string $name - * @return string + * doesn't exist for the provided user */ protected function getNewCalendarName(string $userDestination, string $name): string { $increment = 1; @@ -182,10 +160,6 @@ class MoveCalendar extends Command { /** * Check that moving the calendar won't break shares * - * @param array $calendar - * @param string $userOrigin - * @param string $userDestination - * @param bool $force * @return bool had any shares or not * @throws \InvalidArgumentException */ diff --git a/apps/dav/lib/Command/RemoveInvalidShares.php b/apps/dav/lib/Command/RemoveInvalidShares.php index 4f9e4836a72..e373dc1c678 100644 --- a/apps/dav/lib/Command/RemoveInvalidShares.php +++ b/apps/dav/lib/Command/RemoveInvalidShares.php @@ -37,21 +37,14 @@ use Symfony\Component\Console\Output\OutputInterface; * have no matching principal. Happened because of a bug in the calendar app. */ class RemoveInvalidShares extends Command { - - /** @var IDBConnection */ - private $connection; - /** @var Principal */ - private $principalBackend; - - public function __construct(IDBConnection $connection, - Principal $principalBackend) { + public function __construct( + private IDBConnection $connection, + private Principal $principalBackend, + ) { parent::__construct(); - - $this->connection = $connection; - $this->principalBackend = $principalBackend; } - protected function configure() { + protected function configure(): void { $this ->setName('dav:remove-invalid-shares') ->setDescription('Remove invalid dav shares'); @@ -72,13 +65,13 @@ class RemoveInvalidShares extends Command { } $result->closeCursor(); - return 0; + return self::SUCCESS; } /** * @param string $principaluri */ - private function deleteSharesForPrincipal($principaluri) { + private function deleteSharesForPrincipal($principaluri): void { $delete = $this->connection->getQueryBuilder(); $delete->delete('dav_shares') ->where($delete->expr()->eq('principaluri', $delete->createNamedParameter($principaluri))); diff --git a/apps/dav/lib/Command/RetentionCleanupCommand.php b/apps/dav/lib/Command/RetentionCleanupCommand.php index c9beabc974a..21eb96c235c 100644 --- a/apps/dav/lib/Command/RetentionCleanupCommand.php +++ b/apps/dav/lib/Command/RetentionCleanupCommand.php @@ -31,18 +31,15 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class RetentionCleanupCommand extends Command { - /** @var RetentionService */ - private $service; - - public function __construct(RetentionService $service) { + public function __construct( + private RetentionService $service, + ) { parent::__construct('dav:retention:clean-up'); - - $this->service = $service; } protected function execute(InputInterface $input, OutputInterface $output): int { $this->service->cleanUp(); - return 0; + return self::SUCCESS; } } diff --git a/apps/dav/lib/Command/SendEventReminders.php b/apps/dav/lib/Command/SendEventReminders.php index 697248d71a0..16e3bb65a46 100644 --- a/apps/dav/lib/Command/SendEventReminders.php +++ b/apps/dav/lib/Command/SendEventReminders.php @@ -35,22 +35,11 @@ use Symfony\Component\Console\Output\OutputInterface; * @package OCA\DAV\Command */ class SendEventReminders extends Command { - - /** @var ReminderService */ - protected $reminderService; - - /** @var IConfig */ - protected $config; - - /** - * @param ReminderService $reminderService - * @param IConfig $config - */ - public function __construct(ReminderService $reminderService, - IConfig $config) { + public function __construct( + protected ReminderService $reminderService, + protected IConfig $config, + ) { parent::__construct(); - $this->reminderService = $reminderService; - $this->config = $config; } /** @@ -62,24 +51,20 @@ class SendEventReminders extends Command { ->setDescription('Sends event reminders'); } - /** - * @param InputInterface $input - * @param OutputInterface $output - */ protected function execute(InputInterface $input, OutputInterface $output): int { if ($this->config->getAppValue('dav', 'sendEventReminders', 'yes') !== 'yes') { $output->writeln('<error>Sending event reminders disabled!</error>'); $output->writeln('<info>Please run "php occ config:app:set dav sendEventReminders --value yes"'); - return 1; + return self::FAILURE; } if ($this->config->getAppValue('dav', 'sendEventRemindersMode', 'backgroundjob') !== 'occ') { $output->writeln('<error>Sending event reminders mode set to background-job!</error>'); $output->writeln('<info>Please run "php occ config:app:set dav sendEventRemindersMode --value occ"'); - return 1; + return self::FAILURE; } $this->reminderService->processReminders(); - return 0; + return self::SUCCESS; } } diff --git a/apps/dav/lib/Command/SyncBirthdayCalendar.php b/apps/dav/lib/Command/SyncBirthdayCalendar.php index 6de5357bfde..977fd5a067c 100644 --- a/apps/dav/lib/Command/SyncBirthdayCalendar.php +++ b/apps/dav/lib/Command/SyncBirthdayCalendar.php @@ -35,30 +35,15 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class SyncBirthdayCalendar extends Command { - - /** @var BirthdayService */ - private $birthdayService; - - /** @var IConfig */ - private $config; - - /** @var IUserManager */ - private $userManager; - - /** - * @param IUserManager $userManager - * @param IConfig $config - * @param BirthdayService $birthdayService - */ - public function __construct(IUserManager $userManager, IConfig $config, - BirthdayService $birthdayService) { + public function __construct( + private IUserManager $userManager, + private IConfig $config, + private BirthdayService $birthdayService, + ) { parent::__construct(); - $this->birthdayService = $birthdayService; - $this->config = $config; - $this->userManager = $userManager; } - protected function configure() { + protected function configure(): void { $this ->setName('dav:sync-birthday-calendar') ->setDescription('Synchronizes the birthday calendar') @@ -67,10 +52,6 @@ class SyncBirthdayCalendar extends Command { 'User for whom the birthday calendar will be synchronized'); } - /** - * @param InputInterface $input - * @param OutputInterface $output - */ protected function execute(InputInterface $input, OutputInterface $output): int { $this->verifyEnabled(); @@ -89,7 +70,7 @@ class SyncBirthdayCalendar extends Command { $output->writeln("Start birthday calendar sync for $user"); $this->birthdayService->syncUser($user); - return 0; + return self::SUCCESS; } $output->writeln("Start birthday calendar sync for all users ..."); $p = new ProgressBar($output); @@ -109,10 +90,10 @@ class SyncBirthdayCalendar extends Command { $p->finish(); $output->writeln(''); - return 0; + return self::SUCCESS; } - protected function verifyEnabled() { + protected function verifyEnabled(): void { $isEnabled = $this->config->getAppValue('dav', 'generateBirthdayCalendar', 'yes'); if ($isEnabled !== 'yes') { diff --git a/apps/dav/lib/Command/SyncSystemAddressBook.php b/apps/dav/lib/Command/SyncSystemAddressBook.php index 86a9ea26b73..b05e65249ff 100644 --- a/apps/dav/lib/Command/SyncSystemAddressBook.php +++ b/apps/dav/lib/Command/SyncSystemAddressBook.php @@ -31,23 +31,19 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class SyncSystemAddressBook extends Command { - /** - * @param SyncService $syncService - */ - public function __construct(private SyncService $syncService, private IConfig $config) { + public function __construct( + private SyncService $syncService, + private IConfig $config, + ) { parent::__construct(); } - protected function configure() { + protected function configure(): void { $this ->setName('dav:sync-system-addressbook') ->setDescription('Synchronizes users to the system addressbook'); } - /** - * @param InputInterface $input - * @param OutputInterface $output - */ protected function execute(InputInterface $input, OutputInterface $output): int { $output->writeln('Syncing users ...'); $progress = new ProgressBar($output); @@ -59,6 +55,6 @@ class SyncSystemAddressBook extends Command { $progress->finish(); $output->writeln(''); $this->config->setAppValue('dav', 'needs_system_address_book_sync', 'no'); - return 0; + return self::SUCCESS; } } diff --git a/apps/dav/tests/travis/litmus-v1/script.sh b/apps/dav/tests/travis/litmus-v1/script.sh index 998221c0ab2..a87b5f224f9 100644 --- a/apps/dav/tests/travis/litmus-v1/script.sh +++ b/apps/dav/tests/travis/litmus-v1/script.sh @@ -10,4 +10,4 @@ sleep 30 # run the tests cd /tmp/litmus/litmus-0.13 -make URL=http://127.0.0.1:8888/remote.php/webdav CREDS="admin admin" TESTS="basic copymove props" check +make URL=http://127.0.0.1:8888/remote.php/webdav CREDS="admin admin" TESTS="basic copymove props largefile" check diff --git a/apps/dav/tests/travis/litmus-v2/script.sh b/apps/dav/tests/travis/litmus-v2/script.sh index 9e6ed983861..9fca7b224df 100644 --- a/apps/dav/tests/travis/litmus-v2/script.sh +++ b/apps/dav/tests/travis/litmus-v2/script.sh @@ -10,4 +10,4 @@ sleep 30 # run the tests cd /tmp/litmus/litmus-0.13 -make URL=http://127.0.0.1:8888/remote.php/dav/files/admin CREDS="admin admin" TESTS="basic copymove props" check +make URL=http://127.0.0.1:8888/remote.php/dav/files/admin CREDS="admin admin" TESTS="basic copymove props largefile" check diff --git a/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php b/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php index 687dcd25f8b..75606960e4b 100644 --- a/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php +++ b/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php @@ -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,21 @@ 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; +use Psr\Log\LoggerInterface; 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, + private LoggerInterface $logger, + ) { + parent::__construct($time); $this->setInterval(86400); } @@ -56,6 +57,11 @@ 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) { + $this->logger->info('exception while running files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob', ['exception' => $e]); + } } $result->closeCursor(); } diff --git a/apps/files_sharing/lib/Controller/ExternalSharesController.php b/apps/files_sharing/lib/Controller/ExternalSharesController.php index 4cd09423eaa..ed58cb46352 100644 --- a/apps/files_sharing/lib/Controller/ExternalSharesController.php +++ b/apps/files_sharing/lib/Controller/ExternalSharesController.php @@ -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'); diff --git a/apps/files_sharing/lib/External/Storage.php b/apps/files_sharing/lib/External/Storage.php index 9e6c169e140..e3fe9c7f51e 100644 --- a/apps/files_sharing/lib/External/Storage.php +++ b/apps/files_sharing/lib/External/Storage.php @@ -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,45 @@ 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(); + } + + $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->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'], + 'authType' => \Sabre\DAV\Client::AUTH_BASIC, + 'password' => (string)$options['password'] + ] + ); } public function getWatcher($path = '', $storage = null) { @@ -255,9 +270,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; } diff --git a/apps/files_sharing/tests/ExternalStorageTest.php b/apps/files_sharing/tests/ExternalStorageTest.php index 7709abbf6eb..d180b06d641 100644 --- a/apps/files_sharing/tests/ExternalStorageTest.php +++ b/apps/files_sharing/tests/ExternalStorageTest.php @@ -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, ] |