Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>tags/v14.0.0beta1
@@ -698,17 +698,21 @@ class ShareAPIController extends OCSController { | |||
* @param string $password | |||
* @param string $publicUpload | |||
* @param string $expireDate | |||
* @param string $note | |||
* @return DataResponse | |||
* @throws OCSNotFoundException | |||
* @throws LockedException | |||
* @throws NotFoundException | |||
* @throws OCSBadRequestException | |||
* @throws OCSForbiddenException | |||
* @throws OCSNotFoundException | |||
*/ | |||
public function updateShare( | |||
string $id, | |||
int $permissions = null, | |||
string $password = null, | |||
string $publicUpload = null, | |||
string $expireDate = null | |||
string $expireDate = null, | |||
string $note = null | |||
): DataResponse { | |||
try { | |||
$share = $this->getShareById($id); | |||
@@ -722,10 +726,14 @@ class ShareAPIController extends OCSController { | |||
throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist')); | |||
} | |||
if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) { | |||
if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null && $note === null) { | |||
throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given')); | |||
} | |||
if($note !== null) { | |||
$share->setNote($note); | |||
} | |||
/* | |||
* expirationdate, password and publicUpload only make sense for link shares | |||
*/ |
@@ -506,6 +506,61 @@ class ShareByMailProvider implements IShareProvider { | |||
return true; | |||
} | |||
protected function sendNote(IShare $share) { | |||
$recipient = $share->getSharedWith(); | |||
$filename = $share->getNode()->getName(); | |||
$initiator = $share->getSharedBy(); | |||
$note = $share->getNote(); | |||
$initiatorUser = $this->userManager->get($initiator); | |||
$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator; | |||
$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null; | |||
$plainBodyPart = $this->l->t("%s shared »%s« with you and want to add:\n", [$initiatorDisplayName, $filename]); | |||
$htmlBodyPart = $this->l->t('%s shared »%s« with you and want to add:', [$initiatorDisplayName, $filename]); | |||
$message = $this->mailer->createMessage(); | |||
$emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote', [ | |||
'filename' => $filename, | |||
'note' => $note, | |||
'initiator' => $initiatorDisplayName, | |||
'initiatorEmail' => $initiatorEmailAddress, | |||
'shareWith' => $recipient, | |||
]); | |||
$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName])); | |||
$emailTemplate->addHeader(); | |||
$emailTemplate->addHeading($this->l->t('Note regarding »%s«', [$filename]), false); | |||
$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart); | |||
$emailTemplate->addBodyText($note); | |||
// 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]); | |||
if ($initiatorEmailAddress !== null) { | |||
$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]); | |||
$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan()); | |||
} else { | |||
$emailTemplate->addFooter(); | |||
} | |||
$message->setTo([$recipient]); | |||
$message->useTemplate($emailTemplate); | |||
$this->mailer->send($message); | |||
} | |||
/** | |||
* send auto generated password to the owner. This happens if the admin enforces | |||
* a password for mail shares and forbid to send the password by mail to the recipient | |||
@@ -662,8 +717,13 @@ class ShareByMailProvider implements IShareProvider { | |||
->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy())) | |||
->set('password', $qb->createNamedParameter($share->getPassword())) | |||
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) | |||
->set('note', $qb->createNamedParameter($share->getNote())) | |||
->execute(); | |||
if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') { | |||
$this->sendNote($share); | |||
} | |||
return $share; | |||
} | |||
@@ -0,0 +1,45 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 Bjoern Schiessle <bjoern@schiessle.org> | |||
* | |||
* @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 OC\Core\Migrations; | |||
use OCP\Migration\SimpleMigrationStep; | |||
/** | |||
* add column for share notes | |||
* | |||
* Class Version14000Date20180712153140 | |||
*/ | |||
class Version14000Date20180712153140 extends SimpleMigrationStep { | |||
public function changeSchema(\OCP\Migration\IOutput $output, \Closure $schemaClosure, array $options) { | |||
/** @var ISchemaWrapper $schema */ | |||
$schema = $schemaClosure(); | |||
$table = $schema->getTable('share'); | |||
$table->addColumn('note', 'text', [ | |||
'notnull' => true, | |||
'default' => '' | |||
]); | |||
return $schema; | |||
} | |||
} |
@@ -30,8 +30,13 @@ | |||
namespace OC\Share20; | |||
use OC\Files\Cache\Cache; | |||
use OCP\Defaults; | |||
use OCP\Files\Folder; | |||
use OCP\IL10N; | |||
use OCP\IUser; | |||
use OCP\Mail\IMailer; | |||
use OCP\Share\IShare; | |||
use OCP\Share\IShareHelper; | |||
use OCP\Share\IShareProvider; | |||
use OC\Share20\Exception\InvalidShare; | |||
use OC\Share20\Exception\ProviderException; | |||
@@ -67,6 +72,15 @@ class DefaultShareProvider implements IShareProvider { | |||
/** @var IRootFolder */ | |||
private $rootFolder; | |||
/** @var IMailer */ | |||
private $mailer; | |||
/** @var Defaults */ | |||
private $defaults; | |||
/** @var IL10N */ | |||
private $l; | |||
/** | |||
* DefaultShareProvider constructor. | |||
* | |||
@@ -74,16 +88,25 @@ class DefaultShareProvider implements IShareProvider { | |||
* @param IUserManager $userManager | |||
* @param IGroupManager $groupManager | |||
* @param IRootFolder $rootFolder | |||
* @param IMailer $mailer ; | |||
* @param Defaults $defaults | |||
* @param IL10N $l | |||
*/ | |||
public function __construct( | |||
IDBConnection $connection, | |||
IUserManager $userManager, | |||
IGroupManager $groupManager, | |||
IRootFolder $rootFolder) { | |||
IRootFolder $rootFolder, | |||
IMailer $mailer, | |||
Defaults $defaults, | |||
IL10N $l) { | |||
$this->dbConn = $connection; | |||
$this->userManager = $userManager; | |||
$this->groupManager = $groupManager; | |||
$this->rootFolder = $rootFolder; | |||
$this->mailer = $mailer; | |||
$this->defaults = $defaults; | |||
$this->l = $l; | |||
} | |||
/** | |||
@@ -197,6 +220,9 @@ class DefaultShareProvider implements IShareProvider { | |||
* @return \OCP\Share\IShare The share object | |||
*/ | |||
public function update(\OCP\Share\IShare $share) { | |||
$originalShare = $this->getShareById($share->getId()); | |||
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { | |||
/* | |||
* We allow updating the recipient on user shares. | |||
@@ -211,6 +237,7 @@ class DefaultShareProvider implements IShareProvider { | |||
->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) | |||
->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) | |||
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) | |||
->set('note', $qb->createNamedParameter($share->getNote())) | |||
->execute(); | |||
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { | |||
$qb = $this->dbConn->getQueryBuilder(); | |||
@@ -222,6 +249,7 @@ class DefaultShareProvider implements IShareProvider { | |||
->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) | |||
->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) | |||
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) | |||
->set('note', $qb->createNamedParameter($share->getNote())) | |||
->execute(); | |||
/* | |||
@@ -235,6 +263,7 @@ class DefaultShareProvider implements IShareProvider { | |||
->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) | |||
->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) | |||
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) | |||
->set('note', $qb->createNamedParameter($share->getNote())) | |||
->execute(); | |||
/* | |||
@@ -259,9 +288,15 @@ class DefaultShareProvider implements IShareProvider { | |||
->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) | |||
->set('token', $qb->createNamedParameter($share->getToken())) | |||
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) | |||
->set('note', $qb->createNamedParameter($share->getNote())) | |||
->execute(); | |||
} | |||
if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') { | |||
$this->propagateNote($share); | |||
} | |||
return $share; | |||
} | |||
@@ -1227,4 +1262,98 @@ class DefaultShareProvider implements IShareProvider { | |||
return $best; | |||
} | |||
/** | |||
* propagate notes to the recipients | |||
* | |||
* @param IShare $share | |||
* @throws \OCP\Files\NotFoundException | |||
*/ | |||
private function propagateNote(IShare $share) { | |||
if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { | |||
$user = $this->userManager->get($share->getSharedWith()); | |||
$this->sendNote([$user], $share); | |||
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { | |||
$group = $this->groupManager->get($share->getSharedWith()); | |||
$groupMembers = $group->getUsers(); | |||
$this->sendNote($groupMembers, $share); | |||
} | |||
} | |||
/** | |||
* send note by mail | |||
* | |||
* @param array $recipients | |||
* @param IShare $share | |||
* @throws \OCP\Files\NotFoundException | |||
*/ | |||
private function sendNote(array $recipients, IShare $share) { | |||
$toList = []; | |||
foreach ($recipients as $recipient) { | |||
/** @var IUser $recipient */ | |||
$email = $recipient->getEMailAddress(); | |||
if ($email) { | |||
$toList[$email] = $recipient->getDisplayName(); | |||
} | |||
} | |||
if (!empty($toList)) { | |||
$filename = $share->getNode()->getName(); | |||
$initiator = $share->getSharedBy(); | |||
$note = $share->getNote(); | |||
$initiatorUser = $this->userManager->get($initiator); | |||
$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator; | |||
$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null; | |||
$plainBodyPart = $this->l->t("%s shared »%s« with you and want to add:\n", [$initiatorDisplayName, $filename]); | |||
$htmlBodyPart = $this->l->t('%s shared »%s« with you and want to add:', [$initiatorDisplayName, $filename]); | |||
$message = $this->mailer->createMessage(); | |||
$emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote', [ | |||
'filename' => $filename, | |||
'note' => $note, | |||
'initiator' => $initiatorDisplayName, | |||
'initiatorEmail' => $initiatorEmailAddress, | |||
'shareWith' => $recipient, | |||
]); | |||
$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName])); | |||
$emailTemplate->addHeader(); | |||
$emailTemplate->addHeading($this->l->t('Note regarding »%s«', [$filename]), false); | |||
$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart); | |||
$emailTemplate->addBodyText($note); | |||
// 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]); | |||
if ($initiatorEmailAddress !== null) { | |||
$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]); | |||
$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan()); | |||
} else { | |||
$emailTemplate->addFooter(); | |||
} | |||
if (count($toList) === 1) { | |||
$message->setTo($toList); | |||
} else { | |||
$message->setTo([]); | |||
$message->setBcc($toList); | |||
} | |||
$message->useTemplate($emailTemplate); | |||
$this->mailer->send($message); | |||
} | |||
} | |||
} |
@@ -81,7 +81,10 @@ class ProviderFactory implements IProviderFactory { | |||
$this->serverContainer->getDatabaseConnection(), | |||
$this->serverContainer->getUserManager(), | |||
$this->serverContainer->getGroupManager(), | |||
$this->serverContainer->getLazyRootFolder() | |||
$this->serverContainer->getLazyRootFolder(), | |||
$this->serverContainer->getMailer(), | |||
$this->serverContainer->query(Defaults::class), | |||
$this->serverContainer->getL10N('sharing') | |||
); | |||
} | |||
@@ -57,6 +57,8 @@ class Share implements \OCP\Share\IShare { | |||
private $shareOwner; | |||
/** @var int */ | |||
private $permissions; | |||
/** @var string */ | |||
private $note = ''; | |||
/** @var \DateTime */ | |||
private $expireDate; | |||
/** @var string */ | |||
@@ -308,6 +310,21 @@ class Share implements \OCP\Share\IShare { | |||
return $this->permissions; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function setNote($note) { | |||
$this->note = $note; | |||
return $this; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function getNote() { | |||
return $this->note; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ |
@@ -222,6 +222,24 @@ interface IShare { | |||
*/ | |||
public function getPermissions(); | |||
/** | |||
* Attach a note to a share | |||
* | |||
* @param string $note | |||
* @return \OCP\Share\IShare The modified object | |||
* @since 14.0.0 | |||
*/ | |||
public function setNote($note); | |||
/** | |||
* Get note attached to a share | |||
* | |||
* @return string | |||
* @since 14.0.0 | |||
*/ | |||
public function getNote(); | |||
/** | |||
* Set the expiration date | |||
* |
@@ -29,7 +29,7 @@ | |||
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel | |||
// when updating major/minor version number. | |||
$OC_Version = array(14, 0, 0, 10); | |||
$OC_Version = array(14, 0, 0, 11); | |||
// The human readable string | |||
$OC_VersionString = '14.0.0 alpha'; |