diff --git a/apps/files_sharing/composer/composer/autoload_classmap.php b/apps/files_sharing/composer/composer/autoload_classmap.php index b42d1555263..400df9c9771 100644 --- a/apps/files_sharing/composer/composer/autoload_classmap.php +++ b/apps/files_sharing/composer/composer/autoload_classmap.php @@ -59,6 +59,7 @@ return array( 'OCA\\Files_Sharing\\ISharedMountPoint' => $baseDir . '/../lib/ISharedMountPoint.php', 'OCA\\Files_Sharing\\ISharedStorage' => $baseDir . '/../lib/ISharedStorage.php', 'OCA\\Files_Sharing\\Listener\\BeforeDirectFileDownloadListener' => $baseDir . '/../lib/Listener/BeforeDirectFileDownloadListener.php', + 'OCA\\Files_Sharing\\Listener\\BeforeNodeReadListener' => $baseDir . '/../lib/Listener/BeforeNodeReadListener.php', 'OCA\\Files_Sharing\\Listener\\BeforeZipCreatedListener' => $baseDir . '/../lib/Listener/BeforeZipCreatedListener.php', 'OCA\\Files_Sharing\\Listener\\LoadAdditionalListener' => $baseDir . '/../lib/Listener/LoadAdditionalListener.php', 'OCA\\Files_Sharing\\Listener\\LoadPublicFileRequestAuthListener' => $baseDir . '/../lib/Listener/LoadPublicFileRequestAuthListener.php', diff --git a/apps/files_sharing/composer/composer/autoload_static.php b/apps/files_sharing/composer/composer/autoload_static.php index bb364256947..02bb6d08bb5 100644 --- a/apps/files_sharing/composer/composer/autoload_static.php +++ b/apps/files_sharing/composer/composer/autoload_static.php @@ -74,6 +74,7 @@ class ComposerStaticInitFiles_Sharing 'OCA\\Files_Sharing\\ISharedMountPoint' => __DIR__ . '/..' . '/../lib/ISharedMountPoint.php', 'OCA\\Files_Sharing\\ISharedStorage' => __DIR__ . '/..' . '/../lib/ISharedStorage.php', 'OCA\\Files_Sharing\\Listener\\BeforeDirectFileDownloadListener' => __DIR__ . '/..' . '/../lib/Listener/BeforeDirectFileDownloadListener.php', + 'OCA\\Files_Sharing\\Listener\\BeforeNodeReadListener' => __DIR__ . '/..' . '/../lib/Listener/BeforeNodeReadListener.php', 'OCA\\Files_Sharing\\Listener\\BeforeZipCreatedListener' => __DIR__ . '/..' . '/../lib/Listener/BeforeZipCreatedListener.php', 'OCA\\Files_Sharing\\Listener\\LoadAdditionalListener' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalListener.php', 'OCA\\Files_Sharing\\Listener\\LoadPublicFileRequestAuthListener' => __DIR__ . '/..' . '/../lib/Listener/LoadPublicFileRequestAuthListener.php', diff --git a/apps/files_sharing/lib/AppInfo/Application.php b/apps/files_sharing/lib/AppInfo/Application.php index 6c0d5ca0781..512309d0c55 100644 --- a/apps/files_sharing/lib/AppInfo/Application.php +++ b/apps/files_sharing/lib/AppInfo/Application.php @@ -16,6 +16,7 @@ use OCA\Files_Sharing\External\Manager; use OCA\Files_Sharing\External\MountProvider as ExternalMountProvider; use OCA\Files_Sharing\Helper; use OCA\Files_Sharing\Listener\BeforeDirectFileDownloadListener; +use OCA\Files_Sharing\Listener\BeforeNodeReadListener; use OCA\Files_Sharing\Listener\BeforeZipCreatedListener; use OCA\Files_Sharing\Listener\LoadAdditionalListener; use OCA\Files_Sharing\Listener\LoadPublicFileRequestAuthListener; @@ -42,6 +43,7 @@ use OCP\Federation\ICloudIdManager; use OCP\Files\Config\IMountProviderCollection; use OCP\Files\Events\BeforeDirectFileDownloadEvent; use OCP\Files\Events\BeforeZipCreatedEvent; +use OCP\Files\Events\Node\BeforeNodeReadEvent; use OCP\Group\Events\GroupChangedEvent; use OCP\Group\Events\GroupDeletedEvent; use OCP\Group\Events\UserAddedEvent; @@ -94,6 +96,9 @@ class Application extends App implements IBootstrap { $context->registerEventListener(ShareCreatedEvent::class, UserShareAcceptanceListener::class); $context->registerEventListener(UserAddedEvent::class, UserAddedToGroupListener::class); + // Publish activity for public download + $context->registerEventListener(BeforeNodeReadEvent::class, BeforeNodeReadListener::class); + // Handle download events for view only checks $context->registerEventListener(BeforeZipCreatedEvent::class, BeforeZipCreatedListener::class); $context->registerEventListener(BeforeDirectFileDownloadEvent::class, BeforeDirectFileDownloadListener::class); diff --git a/apps/files_sharing/lib/Listener/BeforeNodeReadListener.php b/apps/files_sharing/lib/Listener/BeforeNodeReadListener.php new file mode 100644 index 00000000000..69f97e2a7c5 --- /dev/null +++ b/apps/files_sharing/lib/Listener/BeforeNodeReadListener.php @@ -0,0 +1,116 @@ + + */ +class BeforeNodeReadListener implements IEventListener { + + public function __construct( + private IUserSession $userSession, + private IRootFolder $rootFolder, + protected \OCP\Activity\IManager $activityManager, + private IRequest $request, + ) { + } + + public function handle(Event $event): void { + if (!($event instanceof BeforeNodeReadEvent)) { + return; + } + + $node = $event->getNode(); + if (!($node instanceof File)) { + return; + } + + try { + $storage = $node->getStorage(); + } catch (NotFoundException) { + return; + } + + if (!$storage->instanceOfStorage(ISharedStorage::class)) { + return; + } + + /** @var ISharedStorage $storage */ + $share = $storage->getShare(); + + $this->singleFileDownloaded($share, $node); + } + + /** + * create activity if a single file was downloaded from a link share + */ + protected function singleFileDownloaded(IShare $share, File $node): void { + $fileId = $node->getId(); + + $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy()); + $userNode = $userFolder->getFirstNodeById($fileId); + $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner()); + $userPath = $userFolder->getRelativePath($userNode?->getPath() ?? '') ?? ''; + $ownerPath = $ownerFolder->getRelativePath($node->getPath()) ?? ''; + + $parameters = [$userPath]; + + if ($share->getShareType() === IShare::TYPE_EMAIL) { + $subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED; + $parameters[] = $share->getSharedWith(); + } elseif ($share->getShareType() === IShare::TYPE_LINK) { + $subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED; + $remoteAddress = $this->request->getRemoteAddress(); + $dateTime = new \DateTime(); + $dateTime = $dateTime->format('Y-m-d H'); + $remoteAddressHash = md5($dateTime . '-' . $remoteAddress); + $parameters[] = $remoteAddressHash; + } else { + return; + } + + $this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath); + + if ($share->getShareOwner() !== $share->getSharedBy()) { + $parameters[0] = $ownerPath; + $this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath); + } + } + + /** + * publish activity + */ + protected function publishActivity( + string $subject, + array $parameters, + string $affectedUser, + int $fileId, + string $filePath, + ): void { + $event = $this->activityManager->generateEvent(); + $event->setApp('files_sharing') + ->setType('public_links') + ->setSubject($subject, $parameters) + ->setAffectedUser($affectedUser) + ->setObject('files', $fileId, $filePath); + $this->activityManager->publish($event); + } +}