diff --git a/apps/files_sharing/appinfo/info.xml b/apps/files_sharing/appinfo/info.xml index a1b91de7de..a90303828f 100644 --- a/apps/files_sharing/appinfo/info.xml +++ b/apps/files_sharing/appinfo/info.xml @@ -41,6 +41,7 @@ Turning the feature off removes shared files and folders on the server for all s OCA\Files_Sharing\Command\CleanupRemoteStorages + OCA\Files_Sharing\Command\ExiprationNotification diff --git a/apps/files_sharing/composer/composer/autoload_classmap.php b/apps/files_sharing/composer/composer/autoload_classmap.php index cb64d44a54..63c31f0a3c 100644 --- a/apps/files_sharing/composer/composer/autoload_classmap.php +++ b/apps/files_sharing/composer/composer/autoload_classmap.php @@ -22,6 +22,7 @@ return array( 'OCA\\Files_Sharing\\Capabilities' => $baseDir . '/../lib/Capabilities.php', 'OCA\\Files_Sharing\\Collaboration\\ShareRecipientSorter' => $baseDir . '/../lib/Collaboration/ShareRecipientSorter.php', 'OCA\\Files_Sharing\\Command\\CleanupRemoteStorages' => $baseDir . '/../lib/Command/CleanupRemoteStorages.php', + 'OCA\\Files_Sharing\\Command\\ExiprationNotification' => $baseDir . '/../lib/Command/ExiprationNotification.php', 'OCA\\Files_Sharing\\Controller\\DeletedShareAPIController' => $baseDir . '/../lib/Controller/DeletedShareAPIController.php', 'OCA\\Files_Sharing\\Controller\\ExternalSharesController' => $baseDir . '/../lib/Controller/ExternalSharesController.php', 'OCA\\Files_Sharing\\Controller\\PublicPreviewController' => $baseDir . '/../lib/Controller/PublicPreviewController.php', @@ -50,6 +51,7 @@ return array( 'OCA\\Files_Sharing\\Migration\\OwncloudGuestShareType' => $baseDir . '/../lib/Migration/OwncloudGuestShareType.php', 'OCA\\Files_Sharing\\Migration\\SetPasswordColumn' => $baseDir . '/../lib/Migration/SetPasswordColumn.php', 'OCA\\Files_Sharing\\MountProvider' => $baseDir . '/../lib/MountProvider.php', + 'OCA\\Files_Sharing\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php', 'OCA\\Files_Sharing\\Scanner' => $baseDir . '/../lib/Scanner.php', 'OCA\\Files_Sharing\\ShareBackend\\File' => $baseDir . '/../lib/ShareBackend/File.php', 'OCA\\Files_Sharing\\ShareBackend\\Folder' => $baseDir . '/../lib/ShareBackend/Folder.php', diff --git a/apps/files_sharing/composer/composer/autoload_static.php b/apps/files_sharing/composer/composer/autoload_static.php index dcfd5c4fe4..659903300c 100644 --- a/apps/files_sharing/composer/composer/autoload_static.php +++ b/apps/files_sharing/composer/composer/autoload_static.php @@ -37,6 +37,7 @@ class ComposerStaticInitFiles_Sharing 'OCA\\Files_Sharing\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php', 'OCA\\Files_Sharing\\Collaboration\\ShareRecipientSorter' => __DIR__ . '/..' . '/../lib/Collaboration/ShareRecipientSorter.php', 'OCA\\Files_Sharing\\Command\\CleanupRemoteStorages' => __DIR__ . '/..' . '/../lib/Command/CleanupRemoteStorages.php', + 'OCA\\Files_Sharing\\Command\\ExiprationNotification' => __DIR__ . '/..' . '/../lib/Command/ExiprationNotification.php', 'OCA\\Files_Sharing\\Controller\\DeletedShareAPIController' => __DIR__ . '/..' . '/../lib/Controller/DeletedShareAPIController.php', 'OCA\\Files_Sharing\\Controller\\ExternalSharesController' => __DIR__ . '/..' . '/../lib/Controller/ExternalSharesController.php', 'OCA\\Files_Sharing\\Controller\\PublicPreviewController' => __DIR__ . '/..' . '/../lib/Controller/PublicPreviewController.php', @@ -65,6 +66,7 @@ class ComposerStaticInitFiles_Sharing 'OCA\\Files_Sharing\\Migration\\OwncloudGuestShareType' => __DIR__ . '/..' . '/../lib/Migration/OwncloudGuestShareType.php', 'OCA\\Files_Sharing\\Migration\\SetPasswordColumn' => __DIR__ . '/..' . '/../lib/Migration/SetPasswordColumn.php', 'OCA\\Files_Sharing\\MountProvider' => __DIR__ . '/..' . '/../lib/MountProvider.php', + 'OCA\\Files_Sharing\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php', 'OCA\\Files_Sharing\\Scanner' => __DIR__ . '/..' . '/../lib/Scanner.php', 'OCA\\Files_Sharing\\ShareBackend\\File' => __DIR__ . '/..' . '/../lib/ShareBackend/File.php', 'OCA\\Files_Sharing\\ShareBackend\\Folder' => __DIR__ . '/..' . '/../lib/ShareBackend/Folder.php', diff --git a/apps/files_sharing/lib/AppInfo/Application.php b/apps/files_sharing/lib/AppInfo/Application.php index d1c5294dae..bba87ba991 100644 --- a/apps/files_sharing/lib/AppInfo/Application.php +++ b/apps/files_sharing/lib/AppInfo/Application.php @@ -32,6 +32,7 @@ namespace OCA\Files_Sharing\AppInfo; use OCA\Files_Sharing\Middleware\OCSShareAPIMiddleware; use OCA\Files_Sharing\Middleware\ShareInfoMiddleware; use OCA\Files_Sharing\MountProvider; +use OCA\Files_Sharing\Notification\Notifier; use OCP\AppFramework\App; use OC\AppFramework\Utility\SimpleContainer; use OCA\Files_Sharing\Controller\ExternalSharesController; @@ -164,6 +165,10 @@ class Application extends App { * Register capabilities */ $container->registerCapability(Capabilities::class); + + /** @var \OCP\Notification\IManager $notifications */ + $notifications = $container->query(\OCP\Notification\IManager::class); + $notifications->registerNotifierService(Notifier::class); } public function registerMountProviders() { diff --git a/apps/files_sharing/lib/Command/ExiprationNotification.php b/apps/files_sharing/lib/Command/ExiprationNotification.php new file mode 100644 index 0000000000..521aab21dc --- /dev/null +++ b/apps/files_sharing/lib/Command/ExiprationNotification.php @@ -0,0 +1,98 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + +namespace OCA\Files_Sharing\Command; + +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\IDBConnection; +use OCP\Notification\IManager as NotificationManager; +use OCP\Share\IManager as ShareManager; +use OCP\Share\IShare; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class ExiprationNotification extends Command { + /** @var NotificationManager */ + private $notificationManager; + /** @var IDBConnection */ + private $connection; + /** @var ITimeFactory */ + private $time; + /** @var ShareManager */ + private $shareManager; + + public function __construct(ITimeFactory $time, + NotificationManager $notificationManager, + IDBConnection $connection, + ShareManager $shareManager) { + parent::__construct(); + + $this->notificationManager = $notificationManager; + $this->connection = $connection; + $this->time = $time; + $this->shareManager = $shareManager; + } + + protected function configure() { + $this + ->setName('sharing:expiration-notification') + ->setDescription('Notify share initiators when a share will expire the next day.'); + } + + public function execute(InputInterface $input, OutputInterface $output) { + //Current time + $minTime = $this->time->getDateTime(); + $minTime->add(new \DateInterval('P1D')); + $minTime->setTime(0,0,0); + + $maxTime = clone $minTime; + $maxTime->setTime(23, 59, 59); + + $shares = $this->shareManager->getAllShares(); + + $now = $this->time->getDateTime(); + + /** @var IShare $share */ + foreach ($shares as $share) { + if ($share->getExpirationDate() === null + || $share->getExpirationDate()->getTimestamp() < $minTime->getTimestamp() + || $share->getExpirationDate()->getTimestamp() > $maxTime->getTimestamp()) { + continue; + } + + $notification = $this->notificationManager->createNotification(); + $notification->setApp('files_sharing') + ->setDateTime($now) + ->setObject('share', $share->getFullId()) + ->setSubject('expiresTomorrow'); + + // Only send to initiator for now + $notification->setUser($share->getSharedBy()); + $this->notificationManager->notify($notification); + } + } + + +} diff --git a/apps/files_sharing/lib/Notification/Notifier.php b/apps/files_sharing/lib/Notification/Notifier.php new file mode 100644 index 0000000000..a9028ec9cf --- /dev/null +++ b/apps/files_sharing/lib/Notification/Notifier.php @@ -0,0 +1,98 @@ + + * + * @author Roeland Jago Douma + * + * @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 . + * + */ + +namespace OCA\Files_Sharing\Notification; + +use OCP\Files\IRootFolder; +use OCP\L10N\IFactory; +use OCP\Notification\AlreadyProcessedException; +use OCP\Notification\INotification; +use OCP\Notification\INotifier; +use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\IManager; + +class Notifier implements INotifier { + + /** @var IFactory */ + protected $l10nFactory; + + /** @var IManager */ + private $shareManager; + + /** @var IRootFolder */ + private $rootFolder; + + public function __construct(IFactory $l10nFactory, + IManager $shareManager, + IRootFolder $rootFolder) { + $this->l10nFactory = $l10nFactory; + $this->shareManager = $shareManager; + $this->rootFolder = $rootFolder; + } + + public function getID(): string { + return 'files_sharing'; + } + + public function getName(): string { + return $this->l10nFactory->get('files_sharing')->t('Files sharing'); + } + + public function prepare(INotification $notification, string $languageCode): INotification { + if ($notification->getApp() !== 'files_sharing' || + $notification->getSubject() !== 'expiresTomorrow') { + throw new \InvalidArgumentException('Unhandled app or subject'); + } + + $l = $this->l10nFactory->get('files_sharing', $languageCode); + $attemptId = $notification->getObjectId(); + + try { + $share = $this->shareManager->getShareById($attemptId); + } catch (ShareNotFound $e) { + throw new AlreadyProcessedException(); + } + + $node = $share->getNode(); + $userFolder = $this->rootFolder->getUserFolder($notification->getUser()); + $path = $userFolder->getRelativePath($node->getPath()); + + $notification + ->setParsedSubject($l->t('Share will expire tomorrow')) + ->setParsedMessage($l->t('One or more of your shares will expire tomorrow')) + ->setRichMessage( + $l->t('Your share of {node} will expire tomorrow'), + [ + 'node' => [ + 'type' => 'file', + 'id' => $node->getId(), + 'name' => $node->getName(), + 'path' => $path, + ], + ] + ); + + return $notification; + } +}