diff options
author | John Molakvoæ <skjnldsv@users.noreply.github.com> | 2021-09-08 20:04:37 +0200 |
---|---|---|
committer | John Molakvoæ <skjnldsv@protonmail.com> | 2021-09-10 08:36:45 +0200 |
commit | c56c317d82e6015739549a606578e963578f4de6 (patch) | |
tree | 0df61d951607776132ee57d1f99d7ffcd7d7099d /apps/files_sharing | |
parent | 2693573be23d7e939ae979bbd910d78c3649fad4 (diff) | |
download | nextcloud-server-c56c317d82e6015739549a606578e963578f4de6.tar.gz nextcloud-server-c56c317d82e6015739549a606578e963578f4de6.zip |
Emit event on link share action
Signed-off-by: John Molakvoæ <skjnldsv@users.noreply.github.com>
Diffstat (limited to 'apps/files_sharing')
5 files changed, 105 insertions, 5 deletions
diff --git a/apps/files_sharing/composer/composer/autoload_classmap.php b/apps/files_sharing/composer/composer/autoload_classmap.php index 8e29f5b5a9c..1bd39d408bb 100644 --- a/apps/files_sharing/composer/composer/autoload_classmap.php +++ b/apps/files_sharing/composer/composer/autoload_classmap.php @@ -37,6 +37,7 @@ return array( 'OCA\\Files_Sharing\\Controller\\ShareesAPIController' => $baseDir . '/../lib/Controller/ShareesAPIController.php', 'OCA\\Files_Sharing\\DeleteOrphanedSharesJob' => $baseDir . '/../lib/DeleteOrphanedSharesJob.php', 'OCA\\Files_Sharing\\Event\\BeforeTemplateRenderedEvent' => $baseDir . '/../lib/Event/BeforeTemplateRenderedEvent.php', + 'OCA\\Files_Sharing\\Event\\ShareLinkAccessedEvent' => $baseDir . '/../lib/Event/ShareLinkAccessedEvent.php', 'OCA\\Files_Sharing\\Event\\ShareMountedEvent' => $baseDir . '/../lib/Event/ShareMountedEvent.php', 'OCA\\Files_Sharing\\Exceptions\\BrokenPath' => $baseDir . '/../lib/Exceptions/BrokenPath.php', 'OCA\\Files_Sharing\\Exceptions\\S2SException' => $baseDir . '/../lib/Exceptions/S2SException.php', diff --git a/apps/files_sharing/composer/composer/autoload_static.php b/apps/files_sharing/composer/composer/autoload_static.php index 2230c086358..b12c759a56e 100644 --- a/apps/files_sharing/composer/composer/autoload_static.php +++ b/apps/files_sharing/composer/composer/autoload_static.php @@ -52,6 +52,7 @@ class ComposerStaticInitFiles_Sharing 'OCA\\Files_Sharing\\Controller\\ShareesAPIController' => __DIR__ . '/..' . '/../lib/Controller/ShareesAPIController.php', 'OCA\\Files_Sharing\\DeleteOrphanedSharesJob' => __DIR__ . '/..' . '/../lib/DeleteOrphanedSharesJob.php', 'OCA\\Files_Sharing\\Event\\BeforeTemplateRenderedEvent' => __DIR__ . '/..' . '/../lib/Event/BeforeTemplateRenderedEvent.php', + 'OCA\\Files_Sharing\\Event\\ShareLinkAccessedEvent' => __DIR__ . '/..' . '/../lib/Event/ShareLinkAccessedEvent.php', 'OCA\\Files_Sharing\\Event\\ShareMountedEvent' => __DIR__ . '/..' . '/../lib/Event/ShareMountedEvent.php', 'OCA\\Files_Sharing\\Exceptions\\BrokenPath' => __DIR__ . '/..' . '/../lib/Exceptions/BrokenPath.php', 'OCA\\Files_Sharing\\Exceptions\\S2SException' => __DIR__ . '/..' . '/../lib/Exceptions/S2SException.php', diff --git a/apps/files_sharing/lib/Controller/ShareController.php b/apps/files_sharing/lib/Controller/ShareController.php index 95c3303ae74..614dae7ffba 100644 --- a/apps/files_sharing/lib/Controller/ShareController.php +++ b/apps/files_sharing/lib/Controller/ShareController.php @@ -48,6 +48,7 @@ use OC_Util; 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; @@ -162,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 @@ -233,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'); } /** @@ -242,10 +248,13 @@ class ShareController extends AuthPublicShareController { * otherwise token * @param int $errorCode * @param string $errorMessage + * * @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; @@ -260,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 @@ -312,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(); } @@ -326,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; } @@ -371,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(); } @@ -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/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/tests/Controller/ShareControllerTest.php b/apps/files_sharing/tests/Controller/ShareControllerTest.php index 07bd845729d..be2616f70fc 100644 --- a/apps/files_sharing/tests/Controller/ShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php @@ -299,7 +299,7 @@ class ShareControllerTest extends \Test\TestCase { return null; }); - $this->eventDispatcher->expects($this->once()) + $this->eventDispatcher->expects($this->exactly(2)) ->method('dispatchTyped') ->with( $this->callback(function ($event) use ($share) { @@ -450,7 +450,7 @@ class ShareControllerTest extends \Test\TestCase { return null; }); - $this->eventDispatcher->expects($this->once()) + $this->eventDispatcher->expects($this->exactly(2)) ->method('dispatchTyped') ->with( $this->callback(function ($event) use ($share) { @@ -605,7 +605,7 @@ class ShareControllerTest extends \Test\TestCase { return null; }); - $this->eventDispatcher->expects($this->once()) + $this->eventDispatcher->expects($this->exactly(2)) ->method('dispatchTyped') ->with( $this->callback(function ($event) use ($share) { |