diff options
author | John Molakvoæ <skjnldsv@users.noreply.github.com> | 2021-10-22 12:47:37 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-22 12:47:37 +0300 |
commit | e673ec0b879e4d32bb468825c549738e342df0f2 (patch) | |
tree | a7a01e82ac7b7aaddb07232a2d71aee85c17d8a9 /apps/files_sharing/lib | |
parent | 7995c6e1dce83becf1e948de960894d481775a6f (diff) | |
parent | 0a359376628b36256aa8332d79b1af1dfc513ce8 (diff) |
Merge branch 'master' into imountpoint-ocp-storage
Diffstat (limited to 'apps/files_sharing/lib')
71 files changed, 728 insertions, 358 deletions
diff --git a/apps/files_sharing/lib/Activity/Filter.php b/apps/files_sharing/lib/Activity/Filter.php index da4539384cf..0ac64301ec8 100644 --- a/apps/files_sharing/lib/Activity/Filter.php +++ b/apps/files_sharing/lib/Activity/Filter.php @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity; use OCP\Activity\IFilter; diff --git a/apps/files_sharing/lib/Activity/Providers/Base.php b/apps/files_sharing/lib/Activity/Providers/Base.php index 843a0c447f1..948d629c8fc 100644 --- a/apps/files_sharing/lib/Activity/Providers/Base.php +++ b/apps/files_sharing/lib/Activity/Providers/Base.php @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Providers; use OCP\Activity\IEvent; diff --git a/apps/files_sharing/lib/Activity/Providers/Downloads.php b/apps/files_sharing/lib/Activity/Providers/Downloads.php index be019bdcd65..a6bbe9a4118 100644 --- a/apps/files_sharing/lib/Activity/Providers/Downloads.php +++ b/apps/files_sharing/lib/Activity/Providers/Downloads.php @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Providers; use OCP\Activity\IEvent; diff --git a/apps/files_sharing/lib/Activity/Providers/Groups.php b/apps/files_sharing/lib/Activity/Providers/Groups.php index 53336057e37..71b1dc65f56 100644 --- a/apps/files_sharing/lib/Activity/Providers/Groups.php +++ b/apps/files_sharing/lib/Activity/Providers/Groups.php @@ -4,7 +4,7 @@ * * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * * @license GNU AGPL version 3 or any later version * @@ -15,14 +15,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Providers; use OCP\Activity\IEvent; diff --git a/apps/files_sharing/lib/Activity/Providers/PublicLinks.php b/apps/files_sharing/lib/Activity/Providers/PublicLinks.php index 2742ded4007..5782166704f 100644 --- a/apps/files_sharing/lib/Activity/Providers/PublicLinks.php +++ b/apps/files_sharing/lib/Activity/Providers/PublicLinks.php @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Providers; use OCP\Activity\IEvent; diff --git a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php index f2217f423ef..29f7c0a298e 100644 --- a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php +++ b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php @@ -15,14 +15,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Providers; use OCP\Activity\IEvent; diff --git a/apps/files_sharing/lib/Activity/Providers/Users.php b/apps/files_sharing/lib/Activity/Providers/Users.php index 828befc471b..8b90ac8ee9d 100644 --- a/apps/files_sharing/lib/Activity/Providers/Users.php +++ b/apps/files_sharing/lib/Activity/Providers/Users.php @@ -4,7 +4,7 @@ * * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Kevin Ndung'u <kevgathuku@gmail.com> * * @license GNU AGPL version 3 or any later version @@ -16,14 +16,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Providers; use OCP\Activity\IEvent; diff --git a/apps/files_sharing/lib/Activity/Settings/PublicLinks.php b/apps/files_sharing/lib/Activity/Settings/PublicLinks.php index 455ae88d5c6..6d91bf16ce2 100644 --- a/apps/files_sharing/lib/Activity/Settings/PublicLinks.php +++ b/apps/files_sharing/lib/Activity/Settings/PublicLinks.php @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Settings; class PublicLinks extends ShareActivitySettings { diff --git a/apps/files_sharing/lib/Activity/Settings/RemoteShare.php b/apps/files_sharing/lib/Activity/Settings/RemoteShare.php index 24fa753437b..4a796132612 100644 --- a/apps/files_sharing/lib/Activity/Settings/RemoteShare.php +++ b/apps/files_sharing/lib/Activity/Settings/RemoteShare.php @@ -15,14 +15,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Settings; class RemoteShare extends ShareActivitySettings { diff --git a/apps/files_sharing/lib/Activity/Settings/ShareActivitySettings.php b/apps/files_sharing/lib/Activity/Settings/ShareActivitySettings.php index 26b307c34e4..e7de3dff8ee 100644 --- a/apps/files_sharing/lib/Activity/Settings/ShareActivitySettings.php +++ b/apps/files_sharing/lib/Activity/Settings/ShareActivitySettings.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Activity\Settings; use OCP\Activity\ActivitySettings; diff --git a/apps/files_sharing/lib/Activity/Settings/Shared.php b/apps/files_sharing/lib/Activity/Settings/Shared.php index 43b26252287..eaef23c1c92 100644 --- a/apps/files_sharing/lib/Activity/Settings/Shared.php +++ b/apps/files_sharing/lib/Activity/Settings/Shared.php @@ -15,14 +15,13 @@ * * 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 + * 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 OCA\Files_Sharing\Activity\Settings; class Shared extends ShareActivitySettings { diff --git a/apps/files_sharing/lib/AppInfo/Application.php b/apps/files_sharing/lib/AppInfo/Application.php index 078a0a5f59d..056d246296f 100644 --- a/apps/files_sharing/lib/AppInfo/Application.php +++ b/apps/files_sharing/lib/AppInfo/Application.php @@ -5,7 +5,7 @@ * @author Bjoern Schiessle <bjoern@schiessle.org> * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Julius Härtl <jus@bitgrid.net> * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> @@ -27,13 +27,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\AppInfo; -use OC\AppFramework\Utility\SimpleContainer; +use OC\Share\Share; use OCA\Files_Sharing\Capabilities; use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent; use OCA\Files_Sharing\External\Manager; +use OCA\Files_Sharing\External\MountProvider as ExternalMountProvider; +use OCA\Files_Sharing\Helper; use OCA\Files_Sharing\Listener\LegacyBeforeTemplateRenderedListener; use OCA\Files_Sharing\Listener\LoadAdditionalListener; use OCA\Files_Sharing\Listener\LoadSidebarListener; @@ -48,68 +49,37 @@ use OCA\Files_Sharing\Notification\Listener; use OCA\Files_Sharing\Notification\Notifier; use OCA\Files\Event\LoadAdditionalScriptsEvent; use OCA\Files\Event\LoadSidebar; +use OCA\Files_Sharing\ShareBackend\File; +use OCA\Files_Sharing\ShareBackend\Folder; use OCP\AppFramework\App; +use OCP\AppFramework\Bootstrap\IBootContext; +use OCP\AppFramework\Bootstrap\IBootstrap; +use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudIdManager; use OCP\Files\Config\IMountProviderCollection; use OCP\Group\Events\UserAddedEvent; use OCP\IDBConnection; use OCP\IGroup; -use OCP\IServerContainer; +use OCP\IUserSession; +use OCP\L10N\IFactory; use OCP\Share\Events\ShareCreatedEvent; +use OCP\Share\IManager; use OCP\Util; use Psr\Container\ContainerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; -class Application extends App { +class Application extends App implements IBootstrap { public const APP_ID = 'files_sharing'; public function __construct(array $urlParams = []) { parent::__construct(self::APP_ID, $urlParams); + } - $container = $this->getContainer(); - - /** @var IServerContainer $server */ - $server = $container->getServer(); - - /** @var IEventDispatcher $dispatcher */ - $dispatcher = $container->query(IEventDispatcher::class); - $oldDispatcher = $container->getServer()->getEventDispatcher(); - $mountProviderCollection = $server->getMountProviderCollection(); - $notifications = $server->getNotificationManager(); - - /** - * Core class wrappers - */ - $container->registerService(Manager::class, function (SimpleContainer $c) use ($server) { - $user = $server->getUserSession()->getUser(); - $uid = $user ? $user->getUID() : null; - return new \OCA\Files_Sharing\External\Manager( - $server->getDatabaseConnection(), - \OC\Files\Filesystem::getMountManager(), - \OC\Files\Filesystem::getLoader(), - $server->getHTTPClientService(), - $server->getNotificationManager(), - $server->query(\OCP\OCS\IDiscoveryService::class), - $server->getCloudFederationProviderManager(), - $server->getCloudFederationFactory(), - $server->getGroupManager(), - $server->getUserManager(), - $uid, - $server->query(IEventDispatcher::class) - ); - }); - - /** - * Middleware - */ - $container->registerMiddleWare(SharingCheckMiddleware::class); - $container->registerMiddleWare(OCSShareAPIMiddleware::class); - $container->registerMiddleWare(ShareInfoMiddleware::class); - - $container->registerService('ExternalMountProvider', function (ContainerInterface $c) { - return new \OCA\Files_Sharing\External\MountProvider( + public function register(IRegistrationContext $context): void { + $context->registerService(ExternalMountProvider::class, function (ContainerInterface $c) { + return new ExternalMountProvider( $c->get(IDBConnection::class), function () use ($c) { return $c->get(Manager::class); @@ -119,15 +89,26 @@ class Application extends App { }); /** - * Register capabilities + * Middleware */ - $container->registerCapability(Capabilities::class); + $context->registerMiddleWare(SharingCheckMiddleware::class); + $context->registerMiddleWare(OCSShareAPIMiddleware::class); + $context->registerMiddleWare(ShareInfoMiddleware::class); + + $context->registerCapability(Capabilities::class); - $notifications->registerNotifierService(Notifier::class); + $context->registerNotifierService(Notifier::class); + } + + public function boot(IBootContext $context): void { + $context->injectFn([$this, 'registerMountProviders']); + $context->injectFn([$this, 'registerEventsScripts']); + $context->injectFn([$this, 'setupSharingMenus']); + + Helper::registerHooks(); - $this->registerMountProviders($mountProviderCollection); - $this->registerEventsScripts($dispatcher, $oldDispatcher); - $this->setupSharingMenus(); + Share::registerBackend('file', File::class); + Share::registerBackend('folder', Folder::class, 'file'); /** * Always add main sharing script @@ -135,12 +116,13 @@ class Application extends App { Util::addScript(self::APP_ID, 'dist/main'); } - protected function registerMountProviders(IMountProviderCollection $mountProviderCollection) { - $mountProviderCollection->registerProvider($this->getContainer()->query(MountProvider::class)); - $mountProviderCollection->registerProvider($this->getContainer()->query('ExternalMountProvider')); + + public function registerMountProviders(IMountProviderCollection $mountProviderCollection, MountProvider $mountProvider, ExternalMountProvider $externalMountProvider) { + $mountProviderCollection->registerProvider($mountProvider); + $mountProviderCollection->registerProvider($externalMountProvider); } - protected function registerEventsScripts(IEventDispatcher $dispatcher, EventDispatcherInterface $oldDispatcher) { + public function registerEventsScripts(IEventDispatcher $dispatcher, EventDispatcherInterface $oldDispatcher) { // sidebar and files scripts $dispatcher->addServiceListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class); $dispatcher->addServiceListener(BeforeTemplateRenderedEvent::class, LegacyBeforeTemplateRenderedListener::class); @@ -165,21 +147,21 @@ class Application extends App { }); } - protected function setupSharingMenus() { - $config = \OC::$server->getConfig(); - - if ($config->getAppValue('core', 'shareapi_enabled', 'yes') !== 'yes' || !class_exists('\OCA\Files\App')) { + public function setupSharingMenus(IManager $shareManager, IFactory $l10nFactory, IUserSession $userSession) { + if (!$shareManager->shareApiEnabled() || !class_exists('\OCA\Files\App')) { return; } + $navigationManager = \OCA\Files\App::getNavigationManager(); // show_Quick_Access stored as string - \OCA\Files\App::getNavigationManager()->add(function () { - $config = \OC::$server->getConfig(); - $l = \OC::$server->getL10N('files_sharing'); + $navigationManager->add(function () use ($shareManager, $l10nFactory, $userSession) { + $l = $l10nFactory->get('files_sharing'); + $user = $userSession->getUser(); + $userId = $user ? $user->getUID() : null; $sharingSublistArray = []; - if (\OCP\Util::isSharingDisabledForUser() === false) { + if ($shareManager->sharingDisabledForUser($userId) === false) { $sharingSublistArray[] = [ 'id' => 'sharingout', 'appname' => 'files_sharing', @@ -197,9 +179,9 @@ class Application extends App { 'name' => $l->t('Shared with you'), ]; - if (\OCP\Util::isSharingDisabledForUser() === false) { + if ($shareManager->sharingDisabledForUser($userId) === false) { // Check if sharing by link is enabled - if ($config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes') { + if ($shareManager->shareApiAllowLinks()) { $sharingSublistArray[] = [ 'id' => 'sharinglinks', 'appname' => 'files_sharing', diff --git a/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php b/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php index 913dbf64284..d35f35d20f2 100644 --- a/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php +++ b/apps/files_sharing/lib/BackgroundJob/FederatedSharesDiscoverJob.php @@ -17,14 +17,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\BackgroundJob; use OC\BackgroundJob\TimedJob; diff --git a/apps/files_sharing/lib/Cache.php b/apps/files_sharing/lib/Cache.php index 3a6ade5a2ac..8729426221b 100644 --- a/apps/files_sharing/lib/Cache.php +++ b/apps/files_sharing/lib/Cache.php @@ -26,14 +26,19 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\Files\Cache\FailedCache; use OC\Files\Cache\Wrapper\CacheJail; +use OC\Files\Search\SearchBinaryOperator; +use OC\Files\Search\SearchComparison; use OC\Files\Storage\Wrapper\Jail; use OCP\Files\Cache\ICacheEntry; +use OCP\Files\Search\ISearchBinaryOperator; +use OCP\Files\Search\ISearchComparison; +use OCP\Files\Search\ISearchOperator; use OCP\Files\StorageNotAvailableException; +use OCP\IUserManager; /** * Metadata cache for shared files @@ -41,15 +46,12 @@ use OCP\Files\StorageNotAvailableException; * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead */ class Cache extends CacheJail { - /** - * @var \OCA\Files_Sharing\SharedStorage - */ + /** @var \OCA\Files_Sharing\SharedStorage */ private $storage; - - /** - * @var ICacheEntry - */ + /** @var ICacheEntry */ private $sourceRootInfo; + /** @var IUserManager */ + private $userManager; private $rootUnchanged = true; @@ -59,11 +61,11 @@ class Cache extends CacheJail { /** * @param \OCA\Files_Sharing\SharedStorage $storage - * @param ICacheEntry $sourceRootInfo */ - public function __construct($storage, ICacheEntry $sourceRootInfo) { + public function __construct($storage, ICacheEntry $sourceRootInfo, IUserManager $userManager) { $this->storage = $storage; $this->sourceRootInfo = $sourceRootInfo; + $this->userManager = $userManager; $this->numericId = $sourceRootInfo->getStorageId(); parent::__construct( @@ -170,7 +172,13 @@ class Cache extends CacheJail { private function getOwnerDisplayName() { if (!$this->ownerDisplayName) { - $this->ownerDisplayName = \OC_User::getDisplayName($this->storage->getOwner('')); + $uid = $this->storage->getOwner(''); + $user = $this->userManager->get($uid); + if ($user) { + $this->ownerDisplayName = $user->getDisplayName(); + } else { + $this->ownerDisplayName = $uid; + } } return $this->ownerDisplayName; } @@ -182,19 +190,19 @@ class Cache extends CacheJail { // Not a valid action for Shared Cache } - public function search($pattern) { - // Do the normal search on the whole storage for non files + public function getQueryFilterForStorage(): ISearchOperator { + // Do the normal jail behavior for non files if ($this->storage->getItemType() !== 'file') { - return parent::search($pattern); - } - - $regex = '/' . str_replace('%', '.*', $pattern) . '/i'; - - $data = $this->get(''); - if (preg_match($regex, $data->getName()) === 1) { - return [$data]; + return parent::getQueryFilterForStorage(); } - return []; + // for single file shares we don't need to do the LIKE + return new SearchBinaryOperator( + ISearchBinaryOperator::OPERATOR_AND, + [ + \OC\Files\Cache\Cache::getQueryFilterForStorage(), + new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()), + ] + ); } } diff --git a/apps/files_sharing/lib/Capabilities.php b/apps/files_sharing/lib/Capabilities.php index 88af806b2f9..c5421fe779a 100644 --- a/apps/files_sharing/lib/Capabilities.php +++ b/apps/files_sharing/lib/Capabilities.php @@ -3,9 +3,11 @@ * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Julius Härtl <jus@bitgrid.net> + * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> * @author Tobias Kaminsky <tobias@kaminsky.me> + * @author Vincent Petry <vincent@nextcloud.com> * * @license AGPL-3.0 * @@ -22,12 +24,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OCP\Capabilities\ICapability; use OCP\Constants; use OCP\IConfig; +use OCP\Share\IManager; /** * Class Capabilities @@ -38,9 +40,12 @@ class Capabilities implements ICapability { /** @var IConfig */ private $config; + /** @var IManager */ + private $shareManager; - public function __construct(IConfig $config) { + public function __construct(IConfig $config, IManager $shareManager) { $this->config = $config; + $this->shareManager = $shareManager; } /** @@ -51,7 +56,7 @@ class Capabilities implements ICapability { public function getCapabilities() { $res = []; - if ($this->config->getAppValue('core', 'shareapi_enabled', 'yes') !== 'yes') { + if (!$this->shareManager->shareApiEnabled()) { $res['api_enabled'] = false; $res['public'] = ['enabled' => false]; $res['user'] = ['send_mail' => false]; @@ -60,10 +65,10 @@ class Capabilities implements ICapability { $res['api_enabled'] = true; $public = []; - $public['enabled'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes'; + $public['enabled'] = $this->shareManager->shareApiAllowLinks(); if ($public['enabled']) { $public['password'] = []; - $public['password']['enforced'] = ($this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes'); + $public['password']['enforced'] = $this->shareManager->shareApiLinkEnforcePassword(); if ($public['password']['enforced']) { $public['password']['askForOptionalPassword'] = false; @@ -73,21 +78,28 @@ class Capabilities implements ICapability { $public['expire_date'] = []; $public['multiple_links'] = true; - $public['expire_date']['enabled'] = $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes'; + $public['expire_date']['enabled'] = $this->shareManager->shareApiLinkDefaultExpireDate(); if ($public['expire_date']['enabled']) { - $public['expire_date']['days'] = $this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7'); - $public['expire_date']['enforced'] = $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes'; + $public['expire_date']['days'] = $this->shareManager->shareApiLinkDefaultExpireDays(); + $public['expire_date']['enforced'] = $this->shareManager->shareApiLinkDefaultExpireDateEnforced(); } $public['expire_date_internal'] = []; - $public['expire_date_internal']['enabled'] = $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes'; + $public['expire_date_internal']['enabled'] = $this->shareManager->shareApiInternalDefaultExpireDate(); if ($public['expire_date_internal']['enabled']) { - $public['expire_date_internal']['days'] = $this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7'); - $public['expire_date_internal']['enforced'] = $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes'; + $public['expire_date_internal']['days'] = $this->shareManager->shareApiInternalDefaultExpireDays(); + $public['expire_date_internal']['enforced'] = $this->shareManager->shareApiInternalDefaultExpireDateEnforced(); + } + + $public['expire_date_remote'] = []; + $public['expire_date_remote']['enabled'] = $this->shareManager->shareApiRemoteDefaultExpireDate(); + if ($public['expire_date_remote']['enabled']) { + $public['expire_date_remote']['days'] = $this->shareManager->shareApiRemoteDefaultExpireDays(); + $public['expire_date_remote']['enforced'] = $this->shareManager->shareApiRemoteDefaultExpireDateEnforced(); } $public['send_mail'] = $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'no') === 'yes'; - $public['upload'] = $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes'; + $public['upload'] = $this->shareManager->shareApiLinkAllowPublicUpload(); $public['upload_files_drop'] = $public['upload']; } $res['public'] = $public; @@ -99,19 +111,22 @@ class Capabilities implements ICapability { // deprecated in favour of 'group', but we need to keep it for now // in order to stay compatible with older clients - $res['group_sharing'] = $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes'; + $res['group_sharing'] = $this->shareManager->allowGroupSharing(); $res['group'] = []; - $res['group']['enabled'] = $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes'; + $res['group']['enabled'] = $this->shareManager->allowGroupSharing(); $res['group']['expire_date']['enabled'] = true; $res['default_permissions'] = (int)$this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL); } //Federated sharing $res['federation'] = [ - 'outgoing' => $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes', + 'outgoing' => $this->shareManager->outgoingServer2ServerSharesAllowed(), 'incoming' => $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'yes', - 'expire_date' => ['enabled' => true] + // old bogus one, expire_date was not working before, keeping for compatibility + 'expire_date' => ['enabled' => true], + // the real deal, signifies that expiration date can be set on federated shares + 'expire_date_supported' => ['enabled' => true], ]; // Sharee searches diff --git a/apps/files_sharing/lib/Collaboration/ShareRecipientSorter.php b/apps/files_sharing/lib/Collaboration/ShareRecipientSorter.php index 5fbeba7dd01..28d0d26c5be 100644 --- a/apps/files_sharing/lib/Collaboration/ShareRecipientSorter.php +++ b/apps/files_sharing/lib/Collaboration/ShareRecipientSorter.php @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Collaboration; use OCP\Collaboration\AutoComplete\ISorter; diff --git a/apps/files_sharing/lib/Command/CleanupRemoteStorages.php b/apps/files_sharing/lib/Command/CleanupRemoteStorages.php index cf0550aef7f..3816a2a5124 100644 --- a/apps/files_sharing/lib/Command/CleanupRemoteStorages.php +++ b/apps/files_sharing/lib/Command/CleanupRemoteStorages.php @@ -2,6 +2,8 @@ /** * @copyright Copyright (c) 2016, ownCloud GmbH. * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Daniel Calviño Sánchez <danxuliu@gmail.com> * @author Joas Schilling <coding@schilljs.com> * @author Jörn Friedrich Dreyer <jfd@butonic.de> * @author Roeland Jago Douma <roeland@famdouma.nl> @@ -21,7 +23,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Command; use OCP\DB\QueryBuilder\IQueryBuilder; diff --git a/apps/files_sharing/lib/Command/ExiprationNotification.php b/apps/files_sharing/lib/Command/ExiprationNotification.php index 748a640a962..e77b41b1835 100644 --- a/apps/files_sharing/lib/Command/ExiprationNotification.php +++ b/apps/files_sharing/lib/Command/ExiprationNotification.php @@ -17,14 +17,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Command; use OCP\AppFramework\Utility\ITimeFactory; diff --git a/apps/files_sharing/lib/Controller/AcceptController.php b/apps/files_sharing/lib/Controller/AcceptController.php index b25382b45f5..c97780d6f0c 100644 --- a/apps/files_sharing/lib/Controller/AcceptController.php +++ b/apps/files_sharing/lib/Controller/AcceptController.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Controller; use OCA\Files_Sharing\AppInfo\Application; diff --git a/apps/files_sharing/lib/Controller/DeletedShareAPIController.php b/apps/files_sharing/lib/Controller/DeletedShareAPIController.php index 75936907fed..1d625b35322 100644 --- a/apps/files_sharing/lib/Controller/DeletedShareAPIController.php +++ b/apps/files_sharing/lib/Controller/DeletedShareAPIController.php @@ -3,12 +3,12 @@ declare(strict_types=1); /** - * + * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl> * * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Daniel Calviño Sánchez <danxuliu@gmail.com> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Julius Härtl <jus@bitgrid.net> * @author Roeland Jago Douma <roeland@famdouma.nl> * @@ -21,14 +21,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Controller; use OCP\App\IAppManager; diff --git a/apps/files_sharing/lib/Controller/ExternalSharesController.php b/apps/files_sharing/lib/Controller/ExternalSharesController.php index 96b9ebffac8..9fab8d4e1a0 100644 --- a/apps/files_sharing/lib/Controller/ExternalSharesController.php +++ b/apps/files_sharing/lib/Controller/ExternalSharesController.php @@ -5,7 +5,6 @@ * @author Björn Schießle <bjoern@schiessle.org> * @author Joas Schilling <coding@schilljs.com> * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> * @@ -24,7 +23,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Controller; use OCP\AppFramework\Controller; diff --git a/apps/files_sharing/lib/Controller/PublicPreviewController.php b/apps/files_sharing/lib/Controller/PublicPreviewController.php index 0e58057351f..4a16afa7ac0 100644 --- a/apps/files_sharing/lib/Controller/PublicPreviewController.php +++ b/apps/files_sharing/lib/Controller/PublicPreviewController.php @@ -15,14 +15,13 @@ * * 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 + * 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 OCA\Files_Sharing\Controller; use OCP\AppFramework\Http; diff --git a/apps/files_sharing/lib/Controller/RemoteController.php b/apps/files_sharing/lib/Controller/RemoteController.php index 72eb8667b96..75684220c52 100644 --- a/apps/files_sharing/lib/Controller/RemoteController.php +++ b/apps/files_sharing/lib/Controller/RemoteController.php @@ -21,7 +21,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Controller; use OCA\Files_Sharing\External\Manager; diff --git a/apps/files_sharing/lib/Controller/SettingsController.php b/apps/files_sharing/lib/Controller/SettingsController.php index 343bec31926..00d627095b8 100644 --- a/apps/files_sharing/lib/Controller/SettingsController.php +++ b/apps/files_sharing/lib/Controller/SettingsController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> * * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Hinrich Mahler <nextcloud@mahlerhome.de> * * @license GNU AGPL version 3 or any later version * @@ -16,14 +17,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Controller; use OCA\Files_Sharing\AppInfo\Application; @@ -36,10 +36,13 @@ class SettingsController extends Controller { /** @var IConfig */ private $config; + /** @var string */ private $userId; - public function __construct(IRequest $request, IConfig $config, string $userId) { + public function __construct(IRequest $request, + IConfig $config, + string $userId) { parent::__construct(Application::APP_ID, $request); $this->config = $config; @@ -53,4 +56,20 @@ class SettingsController extends Controller { $this->config->setUserValue($this->userId, Application::APP_ID, 'default_accept', $accept ? 'yes' : 'no'); return new JSONResponse(); } + + /** + * @NoAdminRequired + */ + public function setUserShareFolder(string $shareFolder): JSONResponse { + $this->config->setUserValue($this->userId, Application::APP_ID, 'share_folder', $shareFolder); + return new JSONResponse(); + } + + /** + * @NoAdminRequired + */ + public function resetUserShareFolder(): JSONResponse { + $this->config->deleteUserValue($this->userId, Application::APP_ID, 'share_folder'); + return new JSONResponse(); + } } diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index 922623aa46f..c9853f1e12c 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -6,13 +6,14 @@ declare(strict_types=1); * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Bjoern Schiessle <bjoern@schiessle.org> + * @author castillo92 <37965565+castillo92@users.noreply.github.com> * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Daniel Calviño Sánchez <danxuliu@gmail.com> * @author Daniel Kesselberg <mail@danielkesselberg.de> * @author Gary Kim <gary@garykim.dev> * @author Georg Ehrke <oc.list@georgehrke.com> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Julius Härtl <jus@bitgrid.net> * @author Lukas Reschke <lukas@statuscode.ch> * @author Maxence Lange <maxence@artificial-owl.com> @@ -22,6 +23,7 @@ declare(strict_types=1); * @author Richard Steinmetz <richard@steinmetz.cloud> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Valdnet <47037905+Valdnet@users.noreply.github.com> * @author Vincent Petry <vincent@nextcloud.com> * @author waleczny <michal@walczak.xyz> * @@ -40,7 +42,6 @@ declare(strict_types=1); * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Controller; use OCA\Files_Sharing\Exceptions\SharingRightsException; @@ -237,7 +238,7 @@ class ShareAPIController extends OCSController { $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith(); $result['share_with_displayname_unique'] = $sharedWith !== null ? ( - $sharedWith->getEMailAddress() !== '' ? $sharedWith->getEMailAddress() : $sharedWith->getUID() + !empty($sharedWith->getSystemEMailAddress()) ? $sharedWith->getSystemEMailAddress() : $sharedWith->getUID() ) : $share->getSharedWith(); $result['status'] = []; @@ -477,7 +478,7 @@ class ShareAPIController extends OCSController { } if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) { - throw new OCSNotFoundException($this->l->t('invalid permissions')); + throw new OCSNotFoundException($this->l->t('Invalid permissions')); } // Shares always require read permissions @@ -587,15 +588,39 @@ class ShareAPIController extends OCSController { throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType])); } + if ($shareWith === null) { + throw new OCSNotFoundException($this->l->t('Please specify a valid federated user ID')); + } + $share->setSharedWith($shareWith); $share->setPermissions($permissions); + if ($expireDate !== '') { + try { + $expireDate = $this->parseDate($expireDate); + $share->setExpirationDate($expireDate); + } catch (\Exception $e) { + throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + } + } } elseif ($shareType === IShare::TYPE_REMOTE_GROUP) { if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) { throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType])); } + if ($shareWith === null) { + throw new OCSNotFoundException($this->l->t('Please specify a valid federated group ID')); + } + $share->setSharedWith($shareWith); $share->setPermissions($permissions); + if ($expireDate !== '') { + try { + $expireDate = $this->parseDate($expireDate); + $share->setExpirationDate($expireDate); + } catch (\Exception $e) { + throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + } + } } elseif ($shareType === IShare::TYPE_CIRCLE) { if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) { throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled')); @@ -1079,7 +1104,7 @@ class ShareAPIController extends OCSController { Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files ], true) ) { - throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links')); + throw new OCSBadRequestException($this->l->t('Cannot change permissions for public share links')); } if ( @@ -1136,7 +1161,7 @@ class ShareAPIController extends OCSController { if ($sendPasswordByTalk === 'true') { if (!$this->appManager->isEnabledForUser('spreed')) { - throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled')); + throw new OCSForbiddenException($this->l->t('"Sending the password by Nextcloud Talk" for sharing a file or folder failed because Nextcloud Talk is not enabled.')); } $share->setSendPasswordByTalk(true); diff --git a/apps/files_sharing/lib/Controller/ShareController.php b/apps/files_sharing/lib/Controller/ShareController.php index 31f13ee2756..614dae7ffba 100644 --- a/apps/files_sharing/lib/Controller/ShareController.php +++ b/apps/files_sharing/lib/Controller/ShareController.php @@ -10,7 +10,7 @@ * @author Georg Ehrke <oc.list@georgehrke.com> * @author j3l11234 <297259024@qq.com> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Jonas Sulzer <jonas@violoncello.ch> * @author Julius Härtl <jus@bitgrid.net> * @author Lukas Reschke <lukas@statuscode.ch> @@ -40,15 +40,15 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Controller; +use OC\Security\CSP\ContentSecurityPolicy; use OC_Files; use OC_Util; -use OC\Security\CSP\ContentSecurityPolicy; use OCA\FederatedFileSharing\FederatedShareProvider; use OCA\Files_Sharing\Activity\Providers\Downloads; use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent; +use OCA\Files_Sharing\Event\ShareLinkAccessedEvent; use OCA\Viewer\Event\LoadViewer; use OCP\Accounts\IAccountManager; use OCP\AppFramework\AuthPublicShareController; @@ -163,6 +163,10 @@ class ShareController extends AuthPublicShareController { $this->shareManager = $shareManager; } + public const SHARE_ACCESS = 'access'; + public const SHARE_AUTH = 'auth'; + public const SHARE_DOWNLOAD = 'download'; + /** * @PublicPage * @NoCSRFRequired @@ -234,6 +238,7 @@ class ShareController extends AuthPublicShareController { protected function authFailed() { $this->emitAccessShareHook($this->share, 403, 'Wrong password'); + $this->emitShareAccessEvent($this->share, self::SHARE_AUTH, 403, 'Wrong password'); } /** @@ -243,10 +248,13 @@ class ShareController extends AuthPublicShareController { * otherwise token * @param int $errorCode * @param string $errorMessage - * @throws \OC\HintException + * + * @throws \OCP\HintException * @throws \OC\ServerNotAvailableException + * + * @deprecated use OCP\Files_Sharing\Event\ShareLinkAccessedEvent */ - protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') { + protected function emitAccessShareHook($share, int $errorCode = 200, string $errorMessage = '') { $itemType = $itemSource = $uidOwner = ''; $token = $share; $exception = null; @@ -261,20 +269,34 @@ class ShareController extends AuthPublicShareController { $exception = $e; } } + \OC_Hook::emit(Share::class, 'share_link_access', [ 'itemType' => $itemType, 'itemSource' => $itemSource, 'uidOwner' => $uidOwner, 'token' => $token, 'errorCode' => $errorCode, - 'errorMessage' => $errorMessage, + 'errorMessage' => $errorMessage ]); + if (!is_null($exception)) { throw $exception; } } /** + * Emit a ShareLinkAccessedEvent event when a share is accessed, downloaded, auth... + */ + protected function emitShareAccessEvent(IShare $share, string $step = '', int $errorCode = 200, string $errorMessage = ''): void { + if ($step !== self::SHARE_ACCESS && + $step !== self::SHARE_AUTH && + $step !== self::SHARE_DOWNLOAD) { + return; + } + $this->eventDispatcher->dispatchTyped(new ShareLinkAccessedEvent($share, $step, $errorCode, $errorMessage)); + } + + /** * Validate the permissions of the share * * @param Share\IShare $share @@ -313,6 +335,7 @@ class ShareController extends AuthPublicShareController { try { $share = $this->shareManager->getShareByToken($this->getToken()); } catch (ShareNotFound $e) { + // The share does not exists, we do not emit an ShareLinkAccessedEvent $this->emitAccessShareHook($this->getToken(), 404, 'Share not found'); throw new NotFoundException(); } @@ -327,10 +350,12 @@ class ShareController extends AuthPublicShareController { try { if ($shareNode instanceof \OCP\Files\File && $path !== '') { $this->emitAccessShareHook($share, 404, 'Share not found'); + $this->emitShareAccessEvent($share, self::SHARE_ACCESS, 404, 'Share not found'); throw new NotFoundException(); } } catch (\Exception $e) { $this->emitAccessShareHook($share, 404, 'Share not found'); + $this->emitShareAccessEvent($share, self::SHARE_ACCESS, 404, 'Share not found'); throw $e; } @@ -343,7 +368,7 @@ class ShareController extends AuthPublicShareController { $ownerAccount = $this->accountManager->getAccount($owner); $ownerName = $ownerAccount->getProperty(IAccountManager::PROPERTY_DISPLAYNAME); - if ($ownerName->getScope() === IAccountManager::VISIBILITY_PUBLIC) { + if ($ownerName->getScope() === IAccountManager::SCOPE_PUBLISHED) { $shareTmpl['owner'] = $owner->getUID(); $shareTmpl['shareOwner'] = $owner->getDisplayName(); } @@ -372,6 +397,7 @@ class ShareController extends AuthPublicShareController { $folderNode = $shareNode->get($path); } catch (\OCP\Files\NotFoundException $e) { $this->emitAccessShareHook($share, 404, 'Share not found'); + $this->emitShareAccessEvent($share, self::SHARE_ACCESS, 404, 'Share not found'); throw new NotFoundException(); } @@ -512,7 +538,8 @@ class ShareController extends AuthPublicShareController { $download = new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']); $downloadAll = new SimpleMenuAction('download', $this->l10n->t('Download all files'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']); $directLink = new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']); - $externalShare = new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['shareOwner'], $shareTmpl['filename']); + // TRANSLATORS The placeholder refers to the software product name as in 'Add to your Nextcloud' + $externalShare = new ExternalShareMenuAction($this->l10n->t('Add to your %s', [$this->defaults->getProductName()]), 'icon-external', $shareTmpl['owner'], $shareTmpl['shareOwner'], $shareTmpl['filename']); $responseComposer = []; @@ -534,6 +561,7 @@ class ShareController extends AuthPublicShareController { $response->setContentSecurityPolicy($csp); $this->emitAccessShareHook($share); + $this->emitShareAccessEvent($share, self::SHARE_ACCESS); return $response; } @@ -596,6 +624,7 @@ class ShareController extends AuthPublicShareController { $node = $node->get($path); } catch (NotFoundException $e) { $this->emitAccessShareHook($share, 404, 'Share not found'); + $this->emitShareAccessEvent($share, self::SHARE_DOWNLOAD, 404, 'Share not found'); return new NotFoundResponse(); } } @@ -637,6 +666,7 @@ class ShareController extends AuthPublicShareController { } $this->emitAccessShareHook($share); + $this->emitShareAccessEvent($share, self::SHARE_DOWNLOAD); $server_params = [ 'head' => $this->request->getMethod() === 'HEAD' ]; diff --git a/apps/files_sharing/lib/Controller/ShareInfoController.php b/apps/files_sharing/lib/Controller/ShareInfoController.php index 315a562abef..429eb91bc92 100644 --- a/apps/files_sharing/lib/Controller/ShareInfoController.php +++ b/apps/files_sharing/lib/Controller/ShareInfoController.php @@ -1,6 +1,6 @@ <?php /** - * + * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl> * * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Controller; use OCA\Files_External\NotFoundException; @@ -48,7 +47,7 @@ class ShareInfoController extends ApiController { * @param IRequest $request * @param IManager $shareManager */ - public function __construct($appName, + public function __construct(string $appName, IRequest $request, IManager $shareManager) { parent::__construct($appName, $request); @@ -59,26 +58,32 @@ class ShareInfoController extends ApiController { /** * @PublicPage * @NoCSRFRequired + * @BruteForceProtection(action=shareinfo) * * @param string $t * @param null $password * @param null $dir * @return JSONResponse - * @throws ShareNotFound */ public function info($t, $password = null, $dir = null) { try { $share = $this->shareManager->getShareByToken($t); } catch (ShareNotFound $e) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + $response = new JSONResponse([], Http::STATUS_NOT_FOUND); + $response->throttle(['token' => $t]); + return $response; } if ($share->getPassword() && !$this->shareManager->checkPassword($share, $password)) { - return new JSONResponse([], Http::STATUS_FORBIDDEN); + $response = new JSONResponse([], Http::STATUS_FORBIDDEN); + $response->throttle(['token' => $t]); + return $response; } if (!($share->getPermissions() & Constants::PERMISSION_READ)) { - return new JSONResponse([], Http::STATUS_FORBIDDEN); + $response = new JSONResponse([], Http::STATUS_FORBIDDEN); + $response->throttle(['token' => $t]); + return $response; } $permissionMask = $share->getPermissions(); diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index 131fe918530..399cd4e00be 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -11,8 +11,9 @@ declare(strict_types=1); * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Daniel Calviño Sánchez <danxuliu@gmail.com> * @author Daniel Kesselberg <mail@danielkesselberg.de> + * @author J0WI <J0WI@users.noreply.github.com> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Julius Härtl <jus@bitgrid.net> * @author Maxence Lange <maxence@nextcloud.com> * @author Morris Jobke <hey@morrisjobke.de> @@ -34,7 +35,6 @@ declare(strict_types=1); * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Controller; use OCP\Constants; @@ -141,10 +141,10 @@ class ShareesAPIController extends OCSController { * @return DataResponse * @throws OCSBadRequestException */ - public function search(string $search = '', string $itemType = null, int $page = 1, int $perPage = 200, $shareType = null, bool $lookup = true): DataResponse { + public function search(string $search = '', string $itemType = null, int $page = 1, int $perPage = 200, $shareType = null, bool $lookup = false): DataResponse { // only search for string larger than a given threshold - $threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0); + $threshold = $this->config->getSystemValueInt('sharing.minSearchStringLength', 0); if (strlen($search) < $threshold) { return new DataResponse($this->result); } @@ -192,7 +192,9 @@ class ShareesAPIController extends OCSController { $shareTypes[] = IShare::TYPE_DECK; } } else { - $shareTypes[] = IShare::TYPE_GROUP; + if ($this->shareManager->allowGroupSharing()) { + $shareTypes[] = IShare::TYPE_GROUP; + } $shareTypes[] = IShare::TYPE_EMAIL; } diff --git a/apps/files_sharing/lib/DeleteOrphanedSharesJob.php b/apps/files_sharing/lib/DeleteOrphanedSharesJob.php index eef44cd3400..6a641734680 100644 --- a/apps/files_sharing/lib/DeleteOrphanedSharesJob.php +++ b/apps/files_sharing/lib/DeleteOrphanedSharesJob.php @@ -22,7 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\BackgroundJob\TimedJob; diff --git a/apps/files_sharing/lib/Event/BeforeTemplateRenderedEvent.php b/apps/files_sharing/lib/Event/BeforeTemplateRenderedEvent.php index 6076d50b1f2..1a889cfebe7 100644 --- a/apps/files_sharing/lib/Event/BeforeTemplateRenderedEvent.php +++ b/apps/files_sharing/lib/Event/BeforeTemplateRenderedEvent.php @@ -17,14 +17,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Event; use OCP\EventDispatcher\Event; diff --git a/apps/files_sharing/lib/Event/ShareLinkAccessedEvent.php b/apps/files_sharing/lib/Event/ShareLinkAccessedEvent.php new file mode 100644 index 00000000000..490ada1eef2 --- /dev/null +++ b/apps/files_sharing/lib/Event/ShareLinkAccessedEvent.php @@ -0,0 +1,68 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2021 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.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 OCA\Files_Sharing\Event; + +use OCP\EventDispatcher\Event; +use OCP\Share\IShare; + +class ShareLinkAccessedEvent extends Event { + /** @var IShare */ + private $share; + + /** @var string */ + private $step; + + /** @var int */ + private $errorCode; + + /** @var string */ + private $errorMessage; + + public function __construct(IShare $share, string $step = '', int $errorCode = 200, string $errorMessage = '') { + parent::__construct(); + $this->share = $share; + $this->step = $step; + $this->errorCode = $errorCode; + $this->errorMessage = $errorMessage; + } + + public function getShare(): IShare { + return $this->share; + } + + public function getStep(): string { + return $this->step; + } + + public function getErrorCode(): int { + return $this->errorCode; + } + + public function getErrorMessage(): string { + return $this->errorMessage; + } +} diff --git a/apps/files_sharing/lib/Event/ShareMountedEvent.php b/apps/files_sharing/lib/Event/ShareMountedEvent.php new file mode 100644 index 00000000000..15184827389 --- /dev/null +++ b/apps/files_sharing/lib/Event/ShareMountedEvent.php @@ -0,0 +1,56 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 Robin Appelman <robin@icewind.nl> + * + * @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 OCA\Files_Sharing\Event; + +use OCA\Files_Sharing\SharedMount; +use OCP\EventDispatcher\Event; +use OCP\Files\Mount\IMountPoint; + +class ShareMountedEvent extends Event { + /** @var SharedMount */ + private $mount; + + /** @var IMountPoint[] */ + private $additionalMounts = []; + + public function __construct(SharedMount $mount) { + parent::__construct(); + $this->mount = $mount; + } + + public function getMount(): SharedMount { + return $this->mount; + } + + public function addAdditionalMount(IMountPoint $mountPoint): void { + $this->additionalMounts[] = $mountPoint; + } + + /** + * @return IMountPoint[] + */ + public function getAdditionalMounts(): array { + return $this->additionalMounts; + } +} diff --git a/apps/files_sharing/lib/Exceptions/BrokenPath.php b/apps/files_sharing/lib/Exceptions/BrokenPath.php index c0679c83314..e9908ac293a 100644 --- a/apps/files_sharing/lib/Exceptions/BrokenPath.php +++ b/apps/files_sharing/lib/Exceptions/BrokenPath.php @@ -4,7 +4,6 @@ * * @author Björn Schießle <bjoern@schiessle.org> * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Morris Jobke <hey@morrisjobke.de> * * @license AGPL-3.0 * @@ -21,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Exceptions; /** diff --git a/apps/files_sharing/lib/Exceptions/S2SException.php b/apps/files_sharing/lib/Exceptions/S2SException.php index e775257034b..c6becc057dd 100644 --- a/apps/files_sharing/lib/Exceptions/S2SException.php +++ b/apps/files_sharing/lib/Exceptions/S2SException.php @@ -3,7 +3,6 @@ * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Björn Schießle <bjoern@schiessle.org> - * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license AGPL-3.0 @@ -21,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Exceptions; /** diff --git a/apps/files_sharing/lib/Exceptions/SharingRightsException.php b/apps/files_sharing/lib/Exceptions/SharingRightsException.php index db346774bdb..f235e56cbe4 100644 --- a/apps/files_sharing/lib/Exceptions/SharingRightsException.php +++ b/apps/files_sharing/lib/Exceptions/SharingRightsException.php @@ -13,14 +13,13 @@ * * 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 + * 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 OCA\Files_Sharing\Exceptions; use Exception; diff --git a/apps/files_sharing/lib/ExpireSharesJob.php b/apps/files_sharing/lib/ExpireSharesJob.php index 85a57e855b8..1e56602a0bf 100644 --- a/apps/files_sharing/lib/ExpireSharesJob.php +++ b/apps/files_sharing/lib/ExpireSharesJob.php @@ -4,7 +4,7 @@ * * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license AGPL-3.0 @@ -22,7 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OCP\AppFramework\Utility\ITimeFactory; diff --git a/apps/files_sharing/lib/External/Cache.php b/apps/files_sharing/lib/External/Cache.php index 6a816b166ae..f8d9a2548a8 100644 --- a/apps/files_sharing/lib/External/Cache.php +++ b/apps/files_sharing/lib/External/Cache.php @@ -2,7 +2,6 @@ /** * @copyright Copyright (c) 2016, ownCloud, Inc. * - * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> * @author Vincent Petry <vincent@nextcloud.com> * @@ -21,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\External; use OCP\Federation\ICloudId; diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index 534dd0d2c51..a48e2a63ae4 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -14,6 +14,7 @@ * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> * @author Stefan Weil <sw@weilnetz.de> + * @author Vincent Petry <vincent@nextcloud.com> * * @license AGPL-3.0 * @@ -37,6 +38,7 @@ use Doctrine\DBAL\Driver\Exception; use OC\Files\Filesystem; use OCA\FederatedFileSharing\Events\FederatedShareAddedEvent; use OCA\Files_Sharing\Helper; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationProviderManager; @@ -46,10 +48,12 @@ use OCP\Http\Client\IClientService; use OCP\IDBConnection; use OCP\IGroupManager; use OCP\IUserManager; +use OCP\IUserSession; use OCP\Notification\IManager; use OCP\OCS\IDiscoveryService; use OCP\Share; use OCP\Share\IShare; +use Psr\Log\LoggerInterface; class Manager { public const STORAGE = '\OCA\Files_Sharing\External\Storage'; @@ -81,7 +85,7 @@ class Manager { /** @var ICloudFederationFactory */ private $cloudFederationFactory; - /** @var IGroupManager */ + /** @var IGroupManager */ private $groupManager; /** @var IUserManager */ @@ -90,23 +94,30 @@ class Manager { /** @var IEventDispatcher */ private $eventDispatcher; - public function __construct(IDBConnection $connection, - \OC\Files\Mount\Manager $mountManager, - IStorageFactory $storageLoader, - IClientService $clientService, - IManager $notificationManager, - IDiscoveryService $discoveryService, - ICloudFederationProviderManager $cloudFederationProviderManager, - ICloudFederationFactory $cloudFederationFactory, - IGroupManager $groupManager, - IUserManager $userManager, - ?string $uid, - IEventDispatcher $eventDispatcher) { + /** @var LoggerInterface */ + private $logger; + + public function __construct( + IDBConnection $connection, + \OC\Files\Mount\Manager $mountManager, + IStorageFactory $storageLoader, + IClientService $clientService, + IManager $notificationManager, + IDiscoveryService $discoveryService, + ICloudFederationProviderManager $cloudFederationProviderManager, + ICloudFederationFactory $cloudFederationFactory, + IGroupManager $groupManager, + IUserManager $userManager, + IUserSession $userSession, + IEventDispatcher $eventDispatcher, + LoggerInterface $logger + ) { + $user = $userSession->getUser(); $this->connection = $connection; $this->mountManager = $mountManager; $this->storageLoader = $storageLoader; $this->clientService = $clientService; - $this->uid = $uid; + $this->uid = $user ? $user->getUID() : null; $this->notificationManager = $notificationManager; $this->discoveryService = $discoveryService; $this->cloudFederationProviderManager = $cloudFederationProviderManager; @@ -114,6 +125,7 @@ class Manager { $this->groupManager = $groupManager; $this->userManager = $userManager; $this->eventDispatcher = $eventDispatcher; + $this->logger = $logger; } /** @@ -219,7 +231,7 @@ class Manager { * @param int $id share id * @return mixed share of false */ - public function getShare($id) { + private function fetchShare($id) { $getShare = $this->connection->prepare(' SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`, `parent`, `share_type`, `password`, `mountpoint_hash` FROM `*PREFIX*share_external` @@ -227,14 +239,46 @@ class Manager { $result = $getShare->execute([$id]); $share = $result->fetch(); $result->closeCursor(); + return $share; + } + + private function fetchUserShare($parentId, $uid) { + $getShare = $this->connection->prepare(' + SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`, `parent`, `share_type`, `password`, `mountpoint_hash` + FROM `*PREFIX*share_external` + WHERE `parent` = ? AND `user` = ?'); + $result = $getShare->execute([$parentId, $uid]); + $share = $result->fetch(); + $result->closeCursor(); + if ($share !== false) { + return $share; + } + return null; + } + + /** + * get share + * + * @param int $id share id + * @return mixed share of false + */ + public function getShare($id) { + $share = $this->fetchShare($id); $validShare = is_array($share) && isset($share['share_type']) && isset($share['user']); // check if the user is allowed to access it if ($validShare && (int)$share['share_type'] === IShare::TYPE_USER && $share['user'] === $this->uid) { return $share; } elseif ($validShare && (int)$share['share_type'] === IShare::TYPE_GROUP) { + $parentId = (int)$share['parent']; + if ($parentId !== -1) { + // we just retrieved a sub-share, switch to the parent entry for verification + $groupShare = $this->fetchShare($parentId); + } else { + $groupShare = $share; + } $user = $this->userManager->get($this->uid); - if ($this->groupManager->get($share['user'])->inGroup($user)) { + if ($this->groupManager->get($groupShare['user'])->inGroup($user)) { return $share; } } @@ -243,6 +287,20 @@ class Manager { } /** + * Updates accepted flag in the database + * + * @param int $id + */ + private function updateAccepted(int $shareId, bool $accepted) : void { + $query = $this->connection->prepare(' + UPDATE `*PREFIX*share_external` + SET `accepted` = ? + WHERE `id` = ?'); + $updateResult = $query->execute([$accepted ? 1 : 0, $shareId]); + $updateResult->closeCursor(); + } + + /** * accept server-to-server share * * @param int $id @@ -254,7 +312,7 @@ class Manager { if ($share) { \OC_Util::setupFS($this->uid); - $shareFolder = Helper::getShareFolder(); + $shareFolder = Helper::getShareFolder(null, $this->uid); $mountPoint = Files::buildNotExistingFileName($shareFolder, $share['name']); $mountPoint = Filesystem::normalizePath($mountPoint); $hash = md5($mountPoint); @@ -269,21 +327,46 @@ class Manager { WHERE `id` = ? AND `user` = ?'); $userShareAccepted = $acceptShare->execute([1, $mountPoint, $hash, $id, $this->uid]); } else { - try { - $this->writeShareToDb( - $share['remote'], - $share['share_token'], - $share['password'], - $share['name'], - $share['owner'], - $this->uid, - $mountPoint, $hash, 1, - $share['remote_id'], - $id, - $share['share_type']); - $result = true; - } catch (Exception $e) { - $result = false; + $parentId = (int)$share['parent']; + if ($parentId !== -1) { + // this is the sub-share + $subshare = $share; + } else { + $subshare = $this->fetchUserShare($id, $this->uid); + } + + if ($subshare !== null) { + try { + $acceptShare = $this->connection->prepare(' + UPDATE `*PREFIX*share_external` + SET `accepted` = ?, + `mountpoint` = ?, + `mountpoint_hash` = ? + WHERE `id` = ? AND `user` = ?'); + $acceptShare->execute([1, $mountPoint, $hash, $subshare['id'], $this->uid]); + $result = true; + } catch (Exception $e) { + $this->logger->emergency('Could not update share', ['exception' => $e]); + $result = false; + } + } else { + try { + $this->writeShareToDb( + $share['remote'], + $share['share_token'], + $share['password'], + $share['name'], + $share['owner'], + $this->uid, + $mountPoint, $hash, 1, + $share['remote_id'], + $id, + $share['share_type']); + $result = true; + } catch (Exception $e) { + $this->logger->emergency('Could not create share', ['exception' => $e]); + $result = false; + } } } if ($userShareAccepted !== false) { @@ -319,23 +402,42 @@ class Manager { $this->processNotification($id); $result = true; } elseif ($share && (int)$share['share_type'] === IShare::TYPE_GROUP) { - try { - $this->writeShareToDb( - $share['remote'], - $share['share_token'], - $share['password'], - $share['name'], - $share['owner'], - $this->uid, - $share['mountpoint'], - $share['mountpoint_hash'], - 0, - $share['remote_id'], - $id, - $share['share_type']); - $result = true; - } catch (Exception $e) { - $result = false; + $parentId = (int)$share['parent']; + if ($parentId !== -1) { + // this is the sub-share + $subshare = $share; + } else { + $subshare = $this->fetchUserShare($id, $this->uid); + } + + if ($subshare !== null) { + try { + $this->updateAccepted((int)$subshare['id'], false); + $result = true; + } catch (Exception $e) { + $this->logger->emergency('Could not update share', ['exception' => $e]); + $result = false; + } + } else { + try { + $this->writeShareToDb( + $share['remote'], + $share['share_token'], + $share['password'], + $share['name'], + $share['owner'], + $this->uid, + $share['mountpoint'], + $share['mountpoint_hash'], + 0, + $share['remote_id'], + $id, + $share['share_type']); + $result = true; + } catch (Exception $e) { + $this->logger->emergency('Could not create share', ['exception' => $e]); + $result = false; + } } $this->processNotification($id); } @@ -366,7 +468,7 @@ class Manager { private function sendFeedbackToRemote($remote, $token, $remoteId, $feedback) { $result = $this->tryOCMEndPoint($remote, $token, $remoteId, $feedback); - if ($result === true) { + if (is_array($result)) { return true; } @@ -402,7 +504,7 @@ class Manager { * @param string $token * @param string $remoteId id of the share * @param string $feedback - * @return bool + * @return array|false */ protected function tryOCMEndPoint($remoteDomain, $token, $remoteId, $feedback) { switch ($feedback) { @@ -498,6 +600,10 @@ class Manager { public function removeShare($mountPoint): bool { $mountPointObj = $this->mountManager->find($mountPoint); + if ($mountPointObj === null) { + $this->logger->error('Mount point to remove share not found', ['mountPoint' => $mountPoint]); + return false; + } $id = $mountPointObj->getStorage()->getCache()->getId(''); $mountPoint = $this->stripPath($mountPoint); @@ -520,22 +626,18 @@ class Manager { } $query = $this->connection->prepare(' - DELETE FROM `*PREFIX*share_external` - WHERE `id` = ? + DELETE FROM `*PREFIX*share_external` + WHERE `id` = ? '); $deleteResult = $query->execute([(int)$share['id']]); $deleteResult->closeCursor(); } elseif ($share !== false && (int)$share['share_type'] === IShare::TYPE_GROUP) { - $query = $this->connection->prepare(' - UPDATE `*PREFIX*share_external` - SET `accepted` = ? - WHERE `id` = ?'); - $updateResult = $query->execute([0, (int)$share['id']]); - $updateResult->closeCursor(); + $this->updateAccepted((int)$share['id'], false); } $this->removeReShares($id); } catch (\Doctrine\DBAL\Exception $ex) { + $this->logger->emergency('Could not update share', ['exception' => $ex]); return false; } @@ -572,24 +674,73 @@ class Manager { */ public function removeUserShares($uid): bool { try { + // TODO: use query builder $getShare = $this->connection->prepare(' - SELECT `remote`, `share_token`, `remote_id` + SELECT `id`, `remote`, `share_type`, `share_token`, `remote_id` FROM `*PREFIX*share_external` - WHERE `user` = ?'); - $result = $getShare->execute([$uid]); + WHERE `user` = ? + AND `share_type` = ?'); + $result = $getShare->execute([$uid, IShare::TYPE_USER]); $shares = $result->fetchAll(); $result->closeCursor(); + foreach ($shares as $share) { $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline'); } - $query = $this->connection->prepare(' - DELETE FROM `*PREFIX*share_external` + $qb = $this->connection->getQueryBuilder(); + $qb->delete('share_external') + // user field can specify a user or a group + ->where($qb->expr()->eq('user', $qb->createNamedParameter($uid))) + ->andWhere( + $qb->expr()->orX( + // delete direct shares + $qb->expr()->eq('share_type', $qb->expr()->literal(IShare::TYPE_USER)), + // delete sub-shares of group shares for that user + $qb->expr()->andX( + $qb->expr()->eq('share_type', $qb->expr()->literal(IShare::TYPE_GROUP)), + $qb->expr()->neq('parent', $qb->expr()->literal(-1)), + ) + ) + ); + $qb->execute(); + } catch (\Doctrine\DBAL\Exception $ex) { + $this->logger->emergency('Could not delete user shares', ['exception' => $ex]); + return false; + } + + return true; + } + + public function removeGroupShares($gid): bool { + try { + $getShare = $this->connection->prepare(' + SELECT `id`, `remote`, `share_type`, `share_token`, `remote_id` + FROM `*PREFIX*share_external` WHERE `user` = ? - '); - $deleteResult = $query->execute([$uid]); - $deleteResult->closeCursor(); + AND `share_type` = ?'); + $result = $getShare->execute([$gid, IShare::TYPE_GROUP]); + $shares = $result->fetchAll(); + $result->closeCursor(); + + $deletedGroupShares = []; + $qb = $this->connection->getQueryBuilder(); + // delete group share entry and matching sub-entries + $qb->delete('share_external') + ->where( + $qb->expr()->orX( + $qb->expr()->eq('id', $qb->createParameter('share_id')), + $qb->expr()->eq('parent', $qb->createParameter('share_parent_id')) + ) + ); + + foreach ($shares as $share) { + $qb->setParameter('share_id', $share['id']); + $qb->setParameter('share_parent_id', $share['id']); + $qb->execute(); + } } catch (\Doctrine\DBAL\Exception $ex) { + $this->logger->emergency('Could not delete user shares', ['exception' => $ex]); return false; } @@ -630,23 +781,44 @@ class Manager { $userGroups[] = $group->getGID(); } - $query = 'SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted` - FROM `*PREFIX*share_external` - WHERE (`user` = ? OR `user` IN (?))'; - $parameters = [$this->uid, implode(',',$userGroups)]; - if (!is_null($accepted)) { - $query .= ' AND `accepted` = ?'; - $parameters[] = (int) $accepted; - } - $query .= ' ORDER BY `id` ASC'; + $qb = $this->connection->getQueryBuilder(); + $qb->select('id', 'share_type', 'parent', 'remote', 'remote_id', 'share_token', 'name', 'owner', 'user', 'mountpoint', 'accepted') + ->from('share_external') + ->where( + $qb->expr()->orX( + $qb->expr()->eq('user', $qb->createNamedParameter($this->uid)), + $qb->expr()->in( + 'user', + $qb->createNamedParameter($userGroups, IQueryBuilder::PARAM_STR_ARRAY) + ) + ) + ) + ->orderBy('id', 'ASC'); - $sharesQuery = $this->connection->prepare($query); try { - $result = $sharesQuery->execute($parameters); + $result = $qb->execute(); $shares = $result->fetchAll(); $result->closeCursor(); - return $shares; + + // remove parent group share entry if we have a specific user share entry for the user + $toRemove = []; + foreach ($shares as $share) { + if ((int)$share['share_type'] === IShare::TYPE_GROUP && (int)$share['parent'] > 0) { + $toRemove[] = $share['parent']; + } + } + $shares = array_filter($shares, function ($share) use ($toRemove) { + return !in_array($share['id'], $toRemove, true); + }); + + if (!is_null($accepted)) { + $shares = array_filter($shares, function ($share) use ($accepted) { + return (bool)$share['accepted'] === $accepted; + }); + } + return array_values($shares); } catch (\Doctrine\DBAL\Exception $e) { + $this->logger->emergency('Error when retrieving shares', ['exception' => $e]); return []; } } diff --git a/apps/files_sharing/lib/External/Mount.php b/apps/files_sharing/lib/External/Mount.php index 12874198811..c8b74202ac7 100644 --- a/apps/files_sharing/lib/External/Mount.php +++ b/apps/files_sharing/lib/External/Mount.php @@ -4,8 +4,8 @@ * * @author Bjoern Schiessle <bjoern@schiessle.org> * @author Björn Schießle <bjoern@schiessle.org> - * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> + * @author szaimen <szaimen@e.mail.de> * * @license AGPL-3.0 * @@ -22,7 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\External; use OC\Files\Mount\MountPoint; @@ -71,7 +70,7 @@ class Mount extends MountPoint implements MoveableMount { } /** - * Get the type of mount point, used to distinguish things like shares and external storages + * Get the type of mount point, used to distinguish things like shares and external storage * in the web interface * * @return string diff --git a/apps/files_sharing/lib/External/MountProvider.php b/apps/files_sharing/lib/External/MountProvider.php index 7eb2491619f..36015162530 100644 --- a/apps/files_sharing/lib/External/MountProvider.php +++ b/apps/files_sharing/lib/External/MountProvider.php @@ -22,7 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\External; use OCP\Federation\ICloudIdManager; diff --git a/apps/files_sharing/lib/External/Scanner.php b/apps/files_sharing/lib/External/Scanner.php index 71187707ad7..8115159d181 100644 --- a/apps/files_sharing/lib/External/Scanner.php +++ b/apps/files_sharing/lib/External/Scanner.php @@ -4,7 +4,6 @@ * * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> * @author Olivier Paroz <github@oparoz.com> * @author Robin Appelman <robin@icewind.nl> * @author Vincent Petry <vincent@nextcloud.com> @@ -24,7 +23,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\External; use OC\ForbiddenException; diff --git a/apps/files_sharing/lib/External/Storage.php b/apps/files_sharing/lib/External/Storage.php index f612aadfb32..7d9e8f31c98 100644 --- a/apps/files_sharing/lib/External/Storage.php +++ b/apps/files_sharing/lib/External/Storage.php @@ -29,7 +29,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\External; use GuzzleHttp\Exception\ClientException; diff --git a/apps/files_sharing/lib/External/Watcher.php b/apps/files_sharing/lib/External/Watcher.php index fb15944a533..6afd1c6d538 100644 --- a/apps/files_sharing/lib/External/Watcher.php +++ b/apps/files_sharing/lib/External/Watcher.php @@ -19,7 +19,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\External; class Watcher extends \OC\Files\Cache\Watcher { diff --git a/apps/files_sharing/lib/Helper.php b/apps/files_sharing/lib/Helper.php index 270eb452419..931301a04c4 100644 --- a/apps/files_sharing/lib/Helper.php +++ b/apps/files_sharing/lib/Helper.php @@ -25,11 +25,11 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\Files\Filesystem; use OC\Files\View; +use OCA\Files_Sharing\AppInfo\Application; class Helper { public static function registerHooks() { @@ -64,16 +64,29 @@ class Helper { /** * get default share folder * - * @param \OC\Files\View $view + * @param \OC\Files\View|null $view + * @param string|null $userId * @return string */ - public static function getShareFolder($view = null) { + public static function getShareFolder(View $view = null, string $userId = null): string { if ($view === null) { $view = Filesystem::getView(); } - $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/'); + + $config = \OC::$server->getConfig(); + $systemDefault = $config->getSystemValue('share_folder', '/'); + $allowCustomShareFolder = $config->getSystemValueBool('sharing.allow_custom_share_folder', true); + + // Init custom shareFolder + $shareFolder = $systemDefault; + if ($userId !== null && $allowCustomShareFolder) { + $shareFolder = $config->getUserValue($userId, Application::APP_ID, 'share_folder', $systemDefault); + } + + // Verify and sanitize path $shareFolder = Filesystem::normalizePath($shareFolder); + // Init path if folder doesn't exists if (!$view->file_exists($shareFolder)) { $dir = ''; $subdirs = explode('/', $shareFolder); diff --git a/apps/files_sharing/lib/Hooks.php b/apps/files_sharing/lib/Hooks.php index b3fe09bf9cf..1c93d913eaf 100644 --- a/apps/files_sharing/lib/Hooks.php +++ b/apps/files_sharing/lib/Hooks.php @@ -24,28 +24,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\Files\Filesystem; -use OCP\EventDispatcher\IEventDispatcher; class Hooks { public static function deleteUser($params) { - $manager = new External\Manager( - \OC::$server->getDatabaseConnection(), - \OC\Files\Filesystem::getMountManager(), - \OC\Files\Filesystem::getLoader(), - \OC::$server->getHTTPClientService(), - \OC::$server->getNotificationManager(), - \OC::$server->query(\OCP\OCS\IDiscoveryService::class), - \OC::$server->getCloudFederationProviderManager(), - \OC::$server->getCloudFederationFactory(), - \OC::$server->getGroupManager(), - \OC::$server->getUserManager(), - $params['uid'], - \OC::$server->query(IEventDispatcher::class) - ); + $manager = \OC::$server->get(External\Manager::class); $manager->removeUserShares($params['uid']); } diff --git a/apps/files_sharing/lib/ISharedStorage.php b/apps/files_sharing/lib/ISharedStorage.php index 07c012fd6ff..9f57984803a 100644 --- a/apps/files_sharing/lib/ISharedStorage.php +++ b/apps/files_sharing/lib/ISharedStorage.php @@ -3,7 +3,6 @@ * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> * * @license AGPL-3.0 @@ -21,7 +20,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; interface ISharedStorage { diff --git a/apps/files_sharing/lib/Listener/LegacyBeforeTemplateRenderedListener.php b/apps/files_sharing/lib/Listener/LegacyBeforeTemplateRenderedListener.php index bd0a668b429..e7e81c3a17a 100644 --- a/apps/files_sharing/lib/Listener/LegacyBeforeTemplateRenderedListener.php +++ b/apps/files_sharing/lib/Listener/LegacyBeforeTemplateRenderedListener.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Listener; use OC\EventDispatcher\SymfonyAdapter; diff --git a/apps/files_sharing/lib/Listener/LoadAdditionalListener.php b/apps/files_sharing/lib/Listener/LoadAdditionalListener.php index 316461e792d..44412023bf8 100644 --- a/apps/files_sharing/lib/Listener/LoadAdditionalListener.php +++ b/apps/files_sharing/lib/Listener/LoadAdditionalListener.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> * - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * * @license GNU AGPL version 3 or any later version * @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Listener; use OCA\Files_Sharing\AppInfo\Application; diff --git a/apps/files_sharing/lib/Listener/LoadSidebarListener.php b/apps/files_sharing/lib/Listener/LoadSidebarListener.php index 636a8c7757e..145ab25f686 100644 --- a/apps/files_sharing/lib/Listener/LoadSidebarListener.php +++ b/apps/files_sharing/lib/Listener/LoadSidebarListener.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> * - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * * @license GNU AGPL version 3 or any later version * @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Listener; use OCA\Files_Sharing\AppInfo\Application; diff --git a/apps/files_sharing/lib/Listener/ShareInteractionListener.php b/apps/files_sharing/lib/Listener/ShareInteractionListener.php index 90fc6e996b3..65ad555f5bd 100644 --- a/apps/files_sharing/lib/Listener/ShareInteractionListener.php +++ b/apps/files_sharing/lib/Listener/ShareInteractionListener.php @@ -6,7 +6,7 @@ declare(strict_types=1); * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> * * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * * @license GNU AGPL version 3 or any later version * @@ -17,14 +17,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Listener; use OCP\Contacts\Events\ContactInteractedWithEvent; diff --git a/apps/files_sharing/lib/Listener/UserAddedToGroupListener.php b/apps/files_sharing/lib/Listener/UserAddedToGroupListener.php index 623591da310..1f3898b3dcb 100644 --- a/apps/files_sharing/lib/Listener/UserAddedToGroupListener.php +++ b/apps/files_sharing/lib/Listener/UserAddedToGroupListener.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Listener; use OCA\Files_Sharing\AppInfo\Application; @@ -61,7 +60,7 @@ class UserAddedToGroupListener implements IEventListener { } // Get all group shares this user has access to now to filter later - $shares = $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_GROUP); + $shares = $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_GROUP, null, -1); foreach ($shares as $share) { // If this is not the new group we can skip it diff --git a/apps/files_sharing/lib/Listener/UserShareAcceptanceListener.php b/apps/files_sharing/lib/Listener/UserShareAcceptanceListener.php index 91c0aa494bb..160a806f8ac 100644 --- a/apps/files_sharing/lib/Listener/UserShareAcceptanceListener.php +++ b/apps/files_sharing/lib/Listener/UserShareAcceptanceListener.php @@ -18,14 +18,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Listener; use OCA\Files_Sharing\AppInfo\Application; diff --git a/apps/files_sharing/lib/Middleware/OCSShareAPIMiddleware.php b/apps/files_sharing/lib/Middleware/OCSShareAPIMiddleware.php index 398682b7833..1c961ffed34 100644 --- a/apps/files_sharing/lib/Middleware/OCSShareAPIMiddleware.php +++ b/apps/files_sharing/lib/Middleware/OCSShareAPIMiddleware.php @@ -1,6 +1,6 @@ <?php /** - * + * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl> * * @author Lukas Reschke <lukas@statuscode.ch> * @author Morris Jobke <hey@morrisjobke.de> @@ -15,14 +15,13 @@ * * 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 + * 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 OCA\Files_Sharing\Middleware; use OCA\Files_Sharing\Controller\ShareAPIController; diff --git a/apps/files_sharing/lib/Middleware/ShareInfoMiddleware.php b/apps/files_sharing/lib/Middleware/ShareInfoMiddleware.php index 52d83cdc836..adc6116af45 100644 --- a/apps/files_sharing/lib/Middleware/ShareInfoMiddleware.php +++ b/apps/files_sharing/lib/Middleware/ShareInfoMiddleware.php @@ -1,6 +1,6 @@ <?php /** - * + * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl> * * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Middleware; use OCA\Files_Sharing\Controller\ShareInfoController; diff --git a/apps/files_sharing/lib/Middleware/SharingCheckMiddleware.php b/apps/files_sharing/lib/Middleware/SharingCheckMiddleware.php index 335b0908a98..b9bab169d1d 100644 --- a/apps/files_sharing/lib/Middleware/SharingCheckMiddleware.php +++ b/apps/files_sharing/lib/Middleware/SharingCheckMiddleware.php @@ -1,6 +1,7 @@ <?php declare(strict_types=1); + /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -26,7 +27,6 @@ declare(strict_types=1); * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\Middleware; use OCA\Files_Sharing\Controller\ExternalSharesController; diff --git a/apps/files_sharing/lib/Migration/OwncloudGuestShareType.php b/apps/files_sharing/lib/Migration/OwncloudGuestShareType.php index a4eaa5b3989..d1ba645f93d 100644 --- a/apps/files_sharing/lib/Migration/OwncloudGuestShareType.php +++ b/apps/files_sharing/lib/Migration/OwncloudGuestShareType.php @@ -14,14 +14,13 @@ * * 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 + * 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 OCA\Files_Sharing\Migration; use OCP\IConfig; diff --git a/apps/files_sharing/lib/Migration/SetAcceptedStatus.php b/apps/files_sharing/lib/Migration/SetAcceptedStatus.php index 386f7299d40..a27f12e87e1 100644 --- a/apps/files_sharing/lib/Migration/SetAcceptedStatus.php +++ b/apps/files_sharing/lib/Migration/SetAcceptedStatus.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Migration; use OCP\DB\QueryBuilder\IQueryBuilder; diff --git a/apps/files_sharing/lib/Migration/SetPasswordColumn.php b/apps/files_sharing/lib/Migration/SetPasswordColumn.php index 859c49f2991..b4de4f574dd 100644 --- a/apps/files_sharing/lib/Migration/SetPasswordColumn.php +++ b/apps/files_sharing/lib/Migration/SetPasswordColumn.php @@ -13,14 +13,13 @@ * * 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 + * 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 OCA\Files_Sharing\Migration; use OCP\IConfig; diff --git a/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php b/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php index 9d485952ac4..50d0cd9e066 100644 --- a/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php +++ b/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php @@ -5,7 +5,9 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Julius Härtl <jus@bitgrid.net> + * @author Vincent Petry <vincent@nextcloud.com> * * @license GNU AGPL version 3 or any later version * @@ -16,15 +18,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Migration; use Closure; diff --git a/apps/files_sharing/lib/Migration/Version21000Date20201223143245.php b/apps/files_sharing/lib/Migration/Version21000Date20201223143245.php index 0138d3298e5..ff7722eaa58 100644 --- a/apps/files_sharing/lib/Migration/Version21000Date20201223143245.php +++ b/apps/files_sharing/lib/Migration/Version21000Date20201223143245.php @@ -5,6 +5,7 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2020 Vincent Petry <vincent@nextcloud.com> * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Vincent Petry <vincent@nextcloud.com> * * @license GNU AGPL version 3 or any later version @@ -16,15 +17,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Migration; use Closure; diff --git a/apps/files_sharing/lib/Migration/Version22000Date20210216084241.php b/apps/files_sharing/lib/Migration/Version22000Date20210216084241.php index e3e8dc8bc55..443f255d031 100644 --- a/apps/files_sharing/lib/Migration/Version22000Date20210216084241.php +++ b/apps/files_sharing/lib/Migration/Version22000Date20210216084241.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Migration; use Closure; diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php index 05328872c15..102e5d96559 100644 --- a/apps/files_sharing/lib/MountProvider.php +++ b/apps/files_sharing/lib/MountProvider.php @@ -26,11 +26,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\Cache\CappedMemoryCache; use OC\Files\View; +use OCA\Files_Sharing\Event\ShareMountedEvent; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\IMountProvider; use OCP\Files\Storage\IStorageFactory; use OCP\IConfig; @@ -55,15 +56,24 @@ class MountProvider implements IMountProvider { */ protected $logger; + /** @var IEventDispatcher */ + protected $eventDispatcher; + /** * @param \OCP\IConfig $config * @param IManager $shareManager * @param ILogger $logger */ - public function __construct(IConfig $config, IManager $shareManager, ILogger $logger) { + public function __construct( + IConfig $config, + IManager $shareManager, + ILogger $logger, + IEventDispatcher $eventDispatcher + ) { $this->config = $config; $this->shareManager = $shareManager; $this->logger = $logger; + $this->eventDispatcher = $eventDispatcher; } @@ -126,7 +136,14 @@ class MountProvider implements IMountProvider { $view, $foldersExistCache ); + + $event = new ShareMountedEvent($mount); + $this->eventDispatcher->dispatchTyped($event); + $mounts[$mount->getMountPoint()] = $mount; + foreach ($event->getAdditionalMounts() as $additionalMount) { + $mounts[$additionalMount->getMountPoint()] = $additionalMount; + } } catch (\Exception $e) { $this->logger->logException($e); $this->logger->error('Error while trying to create shared mount'); diff --git a/apps/files_sharing/lib/Notification/Listener.php b/apps/files_sharing/lib/Notification/Listener.php index 385612959a9..db7939767d6 100644 --- a/apps/files_sharing/lib/Notification/Listener.php +++ b/apps/files_sharing/lib/Notification/Listener.php @@ -17,14 +17,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Notification; use OCP\IGroup; diff --git a/apps/files_sharing/lib/Notification/Notifier.php b/apps/files_sharing/lib/Notification/Notifier.php index 2499896653b..7d79165dd26 100644 --- a/apps/files_sharing/lib/Notification/Notifier.php +++ b/apps/files_sharing/lib/Notification/Notifier.php @@ -19,14 +19,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Notification; use OCP\Files\IRootFolder; diff --git a/apps/files_sharing/lib/Scanner.php b/apps/files_sharing/lib/Scanner.php index 21d2565a4cd..a240d3ffb8f 100644 --- a/apps/files_sharing/lib/Scanner.php +++ b/apps/files_sharing/lib/Scanner.php @@ -3,7 +3,6 @@ * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> * @author Vincent Petry <vincent@nextcloud.com> @@ -23,7 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\Files\ObjectStore\NoopScanner; diff --git a/apps/files_sharing/lib/Settings/Personal.php b/apps/files_sharing/lib/Settings/Personal.php index c265a279393..d3886321f97 100644 --- a/apps/files_sharing/lib/Settings/Personal.php +++ b/apps/files_sharing/lib/Settings/Personal.php @@ -7,6 +7,7 @@ declare(strict_types=1); * * @author Julius Härtl <jus@bitgrid.net> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Hinrich Mahler <nextcloud@mahlerhome.de> * * @license GNU AGPL version 3 or any later version * @@ -17,14 +18,13 @@ declare(strict_types=1); * * 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 + * 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 OCA\Files_Sharing\Settings; use OCA\Files_Sharing\AppInfo\Application; @@ -50,10 +50,16 @@ class Personal implements ISettings { public function getForm(): TemplateResponse { $defaultAcceptSystemConfig = $this->config->getSystemValueBool('sharing.enable_share_accept', false) ? 'no' : 'yes'; + $shareFolderSystemConfig = $this->config->getSystemValue('share_folder', '/'); $acceptDefault = $this->config->getUserValue($this->userId, Application::APP_ID, 'default_accept', $defaultAcceptSystemConfig) === 'yes'; $enforceAccept = $this->config->getSystemValueBool('sharing.force_share_accept', false); + $allowCustomDirectory = $this->config->getSystemValueBool('sharing.allow_custom_share_folder', true); + $shareFolderDefault = $this->config->getUserValue($this->userId, Application::APP_ID, 'share_folder', $shareFolderSystemConfig); $this->initialState->provideInitialState('accept_default', $acceptDefault); $this->initialState->provideInitialState('enforce_accept', $enforceAccept); + $this->initialState->provideInitialState('allow_custom_share_folder', $allowCustomDirectory); + $this->initialState->provideInitialState('share_folder', $shareFolderDefault); + $this->initialState->provideInitialState('default_share_folder', $shareFolderSystemConfig); return new TemplateResponse('files_sharing', 'Settings/personal'); } diff --git a/apps/files_sharing/lib/ShareBackend/File.php b/apps/files_sharing/lib/ShareBackend/File.php index fdaeb0c5814..c84cbd66c67 100644 --- a/apps/files_sharing/lib/ShareBackend/File.php +++ b/apps/files_sharing/lib/ShareBackend/File.php @@ -31,7 +31,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\ShareBackend; use OCA\FederatedFileSharing\FederatedShareProvider; diff --git a/apps/files_sharing/lib/ShareBackend/Folder.php b/apps/files_sharing/lib/ShareBackend/Folder.php index c51740cd6d0..51d0c709d98 100644 --- a/apps/files_sharing/lib/ShareBackend/Folder.php +++ b/apps/files_sharing/lib/ShareBackend/Folder.php @@ -26,7 +26,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing\ShareBackend; class Folder extends File implements \OCP\Share_Backend_Collection { diff --git a/apps/files_sharing/lib/SharedMount.php b/apps/files_sharing/lib/SharedMount.php index be600caef4c..7fd477d07e4 100644 --- a/apps/files_sharing/lib/SharedMount.php +++ b/apps/files_sharing/lib/SharedMount.php @@ -26,7 +26,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\Cache\CappedMemoryCache; @@ -106,7 +105,7 @@ class SharedMount extends MountPoint implements MoveableMount { $folderExistCache->set($parent, $parentExists); } if (!$parentExists) { - $parent = Helper::getShareFolder($this->recipientView); + $parent = Helper::getShareFolder($this->recipientView, $this->user); } $newMountPoint = $this->generateUniqueTarget( diff --git a/apps/files_sharing/lib/SharedStorage.php b/apps/files_sharing/lib/SharedStorage.php index bfd3f3da482..3ded20eb495 100644 --- a/apps/files_sharing/lib/SharedStorage.php +++ b/apps/files_sharing/lib/SharedStorage.php @@ -30,20 +30,22 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; use OC\Files\Cache\FailedCache; use OC\Files\Cache\NullWatcher; +use OC\Files\Cache\Watcher; use OC\Files\Filesystem; use OC\Files\Storage\FailedStorage; use OC\Files\Storage\Wrapper\PermissionsMask; use OC\User\NoUserException; +use OCA\Files_External\Config\ExternalMountPoint; use OCP\Constants; use OCP\Files\Cache\ICacheEntry; use OCP\Files\NotFoundException; use OCP\Files\Storage\IDisableEncryptionStorage; use OCP\Files\Storage\IStorage; +use OCP\IUserManager; use OCP\Lock\ILockingProvider; use OCP\Share\IShare; @@ -381,7 +383,11 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto return new FailedCache(); } - $this->cache = new \OCA\Files_Sharing\Cache($storage, $sourceRoot, $this->superShare); + $this->cache = new \OCA\Files_Sharing\Cache( + $storage, + $sourceRoot, + \OC::$server->get(IUserManager::class) + ); return $this->cache; } @@ -396,7 +402,20 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto return $this->superShare->getShareOwner(); } - public function getWatcher($path = '', $storage = null): NullWatcher { + public function getWatcher($path = '', $storage = null): Watcher { + $mountManager = \OC::$server->getMountManager(); + + // Get node informations + $node = $this->getShare()->getNodeCacheEntry(); + if ($node) { + $mount = $mountManager->findByNumericId($node->getStorageId()); + // If the share is originating from an external storage + if (count($mount) > 0 && $mount[0] instanceof ExternalMountPoint) { + // Propagate original storage scan + return parent::getWatcher($path, $storage); + } + } + // cache updating is handled by the share source return new NullWatcher(); } diff --git a/apps/files_sharing/lib/Updater.php b/apps/files_sharing/lib/Updater.php index 2c9ccd10294..9ce114f495d 100644 --- a/apps/files_sharing/lib/Updater.php +++ b/apps/files_sharing/lib/Updater.php @@ -24,9 +24,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OCA\Files_Sharing; +use OCP\Constants; use OCP\Share\IShare; class Updater { @@ -82,7 +82,12 @@ class Updater { //Ownership is moved over foreach ($shares as $share) { /** @var IShare $share */ + if (!($dstMount->getShare()->getPermissions() & Constants::PERMISSION_SHARE)) { + $shareManager->deleteShare($share); + continue; + } $share->setShareOwner($newOwner); + $share->setPermissions($share->getPermissions() & $dstMount->getShare()->getPermissions()); $shareManager->updateShare($share); } } @@ -94,11 +99,11 @@ class Updater { * @param string $newPath new path relative to data/user/files */ private static function renameChildren($oldPath, $newPath) { - $absNewPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $newPath); - $absOldPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files/' . $oldPath); + $absNewPath = \OC\Files\Filesystem::normalizePath('/' . \OC_User::getUser() . '/files/' . $newPath); + $absOldPath = \OC\Files\Filesystem::normalizePath('/' . \OC_User::getUser() . '/files/' . $oldPath); $mountManager = \OC\Files\Filesystem::getMountManager(); - $mountedShares = $mountManager->findIn('/' . \OCP\User::getUser() . '/files/' . $oldPath); + $mountedShares = $mountManager->findIn('/' . \OC_User::getUser() . '/files/' . $oldPath); foreach ($mountedShares as $mount) { if ($mount->getStorage()->instanceOfStorage(ISharedStorage::class)) { $mountPoint = $mount->getMountPoint(); |