Skip to content

Commit

Permalink
Merge pull request #5897 from nextcloud/add-share-mail-for-user-share
Browse files Browse the repository at this point in the history
Send an email once a file/folder is shared with a user
  • Loading branch information
rullzer authored Aug 1, 2017
2 parents e73fdad + a309fa7 commit c845280
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 11 deletions.
2 changes: 1 addition & 1 deletion apps/files_sharing/lib/Activity/Settings/RemoteShare.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function canChangeMail() {
* @since 11.0.0
*/
public function isDefaultEnabledMail() {
return true;
return false;
}
}

2 changes: 1 addition & 1 deletion apps/files_sharing/lib/Activity/Settings/Shared.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function canChangeMail() {
* @since 11.0.0
*/
public function isDefaultEnabledMail() {
return true;
return false;
}
}

5 changes: 4 additions & 1 deletion lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,10 @@ public function __construct($webRoot, \OC\Config $config) {
$factory,
$c->getUserManager(),
$c->getLazyRootFolder(),
$c->getEventDispatcher()
$c->getEventDispatcher(),
$c->getMailer(),
$c->getURLGenerator(),
$c->getThemingDefaults()
);

return $manager;
Expand Down
101 changes: 100 additions & 1 deletion lib/private/Share20/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use OC\Files\Mount\MoveableMount;
use OC\HintException;
use OC\Share20\Exception\ProviderException;
use OCP\Defaults;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
Expand All @@ -40,7 +41,9 @@
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\ILogger;
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\Mail\IMailer;
use OCP\Security\IHasher;
use OCP\Security\ISecureRandom;
use OCP\Share\Exceptions\GenericShareException;
Expand Down Expand Up @@ -82,6 +85,12 @@ class Manager implements IManager {
private $eventDispatcher;
/** @var LegacyHooks */
private $legacyHooks;
/** @var IMailer */
private $mailer;
/** @var IURLGenerator */
private $urlGenerator;
/** @var \OC_Defaults */
private $defaults;


/**
Expand All @@ -98,6 +107,9 @@ class Manager implements IManager {
* @param IUserManager $userManager
* @param IRootFolder $rootFolder
* @param EventDispatcher $eventDispatcher
* @param IMailer $mailer
* @param IURLGenerator $urlGenerator
* @param \OC_Defaults $defaults
*/
public function __construct(
ILogger $logger,
Expand All @@ -110,7 +122,10 @@ public function __construct(
IProviderFactory $factory,
IUserManager $userManager,
IRootFolder $rootFolder,
EventDispatcher $eventDispatcher
EventDispatcher $eventDispatcher,
IMailer $mailer,
IURLGenerator $urlGenerator,
\OC_Defaults $defaults
) {
$this->logger = $logger;
$this->config = $config;
Expand All @@ -125,6 +140,9 @@ public function __construct(
$this->eventDispatcher = $eventDispatcher;
$this->sharingDisabledForUsersCache = new CappedMemoryCache();
$this->legacyHooks = new LegacyHooks($this->eventDispatcher);
$this->mailer = $mailer;
$this->urlGenerator = $urlGenerator;
$this->defaults = $defaults;
}

/**
Expand Down Expand Up @@ -664,9 +682,90 @@ public function createShare(\OCP\Share\IShare $share) {

\OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);

if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
$user = $this->userManager->get($share->getSharedWith());
if ($user !== null) {
$emailAddress = $user->getEMailAddress();
if ($emailAddress !== null && $emailAddress !== '') {
$this->sendMailNotification(
$share->getNode()->getName(),
$this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', [ 'fileid' => $share->getNode()->getId() ]),
$share->getSharedBy(),
$emailAddress
);
$this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
} else {
$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
}
} else {
$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
}
}

return $share;
}

/**
* @param string $filename file/folder name
* @param string $link link to the file/folder
* @param string $initiator user ID of share sender
* @param string $shareWith email address of share receiver
* @throws \Exception If mail couldn't be sent
*/
protected function sendMailNotification($filename,
$link,
$initiator,
$shareWith) {
$initiatorUser = $this->userManager->get($initiator);
$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));

$message = $this->mailer->createMessage();

$emailTemplate = $this->mailer->createEMailTemplate();

$emailTemplate->addHeader();
$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);

$emailTemplate->addBodyText(
$text . ' ' . $this->l->t('Click the button below to open it.'),
$text
);
$emailTemplate->addBodyButton(
$this->l->t('Open »%s«', [$filename]),
$link
);

$message->setTo([$shareWith]);

// The "From" contains the sharers name
$instanceName = $this->defaults->getName();
$senderName = $this->l->t(
'%s via %s',
[
$initiatorDisplayName,
$instanceName
]
);
$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);

// The "Reply-To" is set to the sharer if an mail address is configured
// also the default footer contains a "Do not reply" which needs to be adjusted.
$initiatorEmail = $initiatorUser->getEMailAddress();
if($initiatorEmail !== null) {
$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
} else {
$emailTemplate->addFooter();
}

$message->setSubject($subject);
$message->setPlainBody($emailTemplate->renderText());
$message->setHtmlBody($emailTemplate->renderHtml());
$this->mailer->send($message);
}

/**
* Update a share
*
Expand Down
47 changes: 40 additions & 7 deletions tests/lib/Share20/ManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use OC\Files\Mount\MoveableMount;
use OC\HintException;
use OC\Share20\DefaultShareProvider;
use OCP\Defaults;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
Expand All @@ -31,8 +32,10 @@
use OCP\Files\Storage;
use OCP\IGroup;
use OCP\IServerContainer;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Mail\IMailer;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
Expand Down Expand Up @@ -85,6 +88,12 @@ class ManagerTest extends \Test\TestCase {
protected $rootFolder;
/** @var EventDispatcher | \PHPUnit_Framework_MockObject_MockObject */
protected $eventDispatcher;
/** @var IMailer|\PHPUnit_Framework_MockObject_MockObject */
protected $mailer;
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
protected $urlGenerator;
/** @var \OC_Defaults|\PHPUnit_Framework_MockObject_MockObject */
protected $defaults;

public function setUp() {

Expand All @@ -97,6 +106,9 @@ public function setUp() {
$this->userManager = $this->createMock(IUserManager::class);
$this->rootFolder = $this->createMock(IRootFolder::class);
$this->eventDispatcher = $this->createMock(EventDispatcher::class);
$this->mailer = $this->createMock(IMailer::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->defaults = $this->createMock(\OC_Defaults::class);

$this->l = $this->createMock(IL10N::class);
$this->l->method('t')
Expand All @@ -117,7 +129,10 @@ public function setUp() {
$this->factory,
$this->userManager,
$this->rootFolder,
$this->eventDispatcher
$this->eventDispatcher,
$this->mailer,
$this->urlGenerator,
$this->defaults
);

$this->defaultProvider = $this->createMock(DefaultShareProvider::class);
Expand All @@ -141,7 +156,10 @@ private function createManagerMock() {
$this->factory,
$this->userManager,
$this->rootFolder,
$this->eventDispatcher
$this->eventDispatcher,
$this->mailer,
$this->urlGenerator,
$this->defaults
]);
}

Expand Down Expand Up @@ -2108,7 +2126,10 @@ public function testGetShareByToken() {
$factory,
$this->userManager,
$this->rootFolder,
$this->eventDispatcher
$this->eventDispatcher,
$this->mailer,
$this->urlGenerator,
$this->defaults
);

$share = $this->createMock(IShare::class);
Expand Down Expand Up @@ -2147,7 +2168,10 @@ public function testGetShareByTokenWithException() {
$factory,
$this->userManager,
$this->rootFolder,
$this->eventDispatcher
$this->eventDispatcher,
$this->mailer,
$this->urlGenerator,
$this->defaults
);

$share = $this->createMock(IShare::class);
Expand Down Expand Up @@ -2795,7 +2819,10 @@ public function testShareProviderExists($shareType, $expected) {
$factory,
$this->userManager,
$this->rootFolder,
$this->eventDispatcher
$this->eventDispatcher,
$this->mailer,
$this->urlGenerator,
$this->defaults
);
$this->assertSame($expected,
$manager->shareProviderExists($shareType)
Expand Down Expand Up @@ -2823,7 +2850,10 @@ public function testGetSharesInFolder() {
$factory,
$this->userManager,
$this->rootFolder,
$this->eventDispatcher
$this->eventDispatcher,
$this->mailer,
$this->urlGenerator,
$this->defaults
);

$factory->setProvider($this->defaultProvider);
Expand Down Expand Up @@ -2882,7 +2912,10 @@ public function testGetAccessList() {
$factory,
$this->userManager,
$this->rootFolder,
$this->eventDispatcher
$this->eventDispatcher,
$this->mailer,
$this->urlGenerator,
$this->defaults
);

$factory->setProvider($this->defaultProvider);
Expand Down

0 comments on commit c845280

Please sign in to comment.