apps/files_sharing/lib/Controller/NotificationController.php
<?php
/**
* @author Semih Serhat Karakaya <karakayasemi@itu.edu.tr>
*
* @copyright Copyright (c) 2019, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Files_Sharing\Controller;
use OC\OCS\Result;
use OC\Security\TrustedDomainHelper;
use OC\Share\MailNotifications;
use OCP\AppFramework\OCSController;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Share;
use OCP\Share\Exceptions\GenericShareException;
class NotificationController extends OCSController {
/** @var MailNotifications */
private $mailNotifications;
/** @var IUserSession */
private $userSession;
/** @var IUserManager */
private $userManager;
/** @var IGroupManager */
private $groupManager;
/** @var IRootFolder */
private $rootFolder;
/** @var IL10N */
private $l;
private TrustedDomainHelper $trustedDomainHelper;
public function __construct(
string $appName,
IRequest $request,
MailNotifications $mailNotifications,
IUserSession $userSession,
IUserManager $userManager,
IGroupManager $groupManager,
IRootFolder $rootFolder,
IL10N $l,
TrustedDomainHelper $trustedDomainHelper
) {
parent::__construct($appName, $request);
$this->mailNotifications = $mailNotifications;
$this->userSession = $userSession;
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->rootFolder = $rootFolder;
$this->l = $l;
$this->trustedDomainHelper = $trustedDomainHelper;
}
/**
* @NoCSRFRequired
* @NoAdminRequired
*
* @param string $link URL of the shared link
* @param string[] $recipients
* @param string $personalNote Sender's personal note about share
* @return Result
*/
public function notifyPublicLinkRecipientsByEmail($link, $recipients, $personalNote) {
# verify that the link is for a trusted domain
if (!$this->trustedDomainHelper->isUrlTrusted($link)) {
return new Result(null, 400, "Invalid shared link");
}
$message = null;
$code = 100;
$sender = $this->userSession->getUser();
$result = $recipients;
if ($sender) {
try {
$result = $this->mailNotifications->sendLinkShareMail(
$sender,
$recipients,
$link,
$personalNote
);
} catch (GenericShareException | NotFoundException $e) {
$code = $e->getCode() === 0 ? 403 : $e->getCode();
return new Result(null, $code, $e->getHint());
}
}
if (!empty($result)) {
$message = $this->l->t(
"Couldn't send mail to following recipient(s): %s ",
\implode(', ', $result)
);
$code = 400;
}
return new Result(null, $code, $message);
}
/**
* Send a notification to share recipient(s)
*
* @NoCSRFRequired
* @NoAdminRequired
*
* @param int $itemSource
* @param string $itemType
* @param int $shareType
* @param string $recipient
*
* @return Result
*/
public function notifyRecipients($itemSource, $itemType, $shareType, $recipient) {
$recipientList = [];
$sender = $this->userSession->getUser();
if ($shareType === Share::SHARE_TYPE_USER) {
$recipientList[] = $this->userManager->get($recipient);
} elseif ($shareType === Share::SHARE_TYPE_GROUP) {
$group = $this->groupManager->get($recipient);
$recipientList = $group->searchUsers('');
}
// don't send a mail to the user who shared the file
$recipientList = \array_filter($recipientList, function ($user) {
/** @var IUser $user */
return $user->getUID() !== $this->userSession->getUser()->getUID();
});
$userFolder = $this->rootFolder->getUserFolder($sender->getUID());
$nodes = $userFolder->getById($itemSource, true);
$node = $nodes[0] ?? null;
try {
$result = $this->mailNotifications->sendInternalShareMail($sender, $node, $shareType, $recipientList);
} catch (GenericShareException $e) {
$code = $e->getCode() === 0 ? 403 : $e->getCode();
return new Result(null, $code, $e->getHint());
}
// if we were able to send to at least one recipient, mark as sent
// allowing the user to resend would spam users who already got a notification
if (\count($result) < \count($recipientList)) {
// FIXME: migrate to a new share API
Share::setSendMailStatus($itemType, $itemSource, $shareType, $recipient, true);
}
if (empty($result)) {
$message = null;
$data = ['status' => 'success'];
} else {
$message = $this->l->t(
"Couldn't send mail to following recipient(s): %s ",
\implode(', ', $result)
);
$data = ['status' => 'error'];
}
return new Result($data, 200, $message);
}
/**
* Just mark a notification to share recipient(s) as sent
*
* @NoCSRFRequired
* @NoAdminRequired
*
* @param int $itemSource
* @param string $itemType
* @param int $shareType
* @param string $recipient
*
* @return Result
*/
public function notifyRecipientsDisabled($itemSource, $itemType, $shareType, $recipient) {
// FIXME: migrate to a new share API
Share::setSendMailStatus($itemType, $itemSource, $shareType, $recipient, true);
return new Result(['status' => 'success']);
}
}