mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
chore(files_sharing): refactor mail handling
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
This commit is contained in:
parent
d388370c3b
commit
c253112cf7
3 changed files with 88 additions and 40 deletions
|
|
@ -2040,18 +2040,49 @@ class ShareAPIController extends OCSController {
|
|||
*/
|
||||
#[NoAdminRequired]
|
||||
#[BruteForceProtection(action: 'sendShareEmail')]
|
||||
public function sendShareEmail(string $id, $emails = []) {
|
||||
public function sendShareEmail(string $id, $password = '') {
|
||||
try {
|
||||
$share = $this->getShareById($id);
|
||||
|
||||
if (!$this->canAccessShare($share, false)) {
|
||||
throw new OCSNotFoundException($this->l->t('Wrong share ID, share does not exist'));
|
||||
}
|
||||
|
||||
if (!$this->canEditShare($share)) {
|
||||
throw new OCSForbiddenException('You are not allowed to send mail notifications');
|
||||
}
|
||||
|
||||
// For mail and link shares, the user must be
|
||||
// the owner of the share, not only the file owner.
|
||||
if ($share->getShareType() === IShare::TYPE_EMAIL
|
||||
|| $share->getShareType() === IShare::TYPE_LINK){
|
||||
if ($share->getSharedBy() !== $this->currentUser) {
|
||||
throw new OCSForbiddenException('You are not allowed to send mail notifications');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$provider = $this->factory->getProviderForType($share->getShareType());
|
||||
if (!($provider instanceof IShareProviderWithNotification)) {
|
||||
throw new OCSBadRequestException($this->l->t('No mail notification configured for this share type'));
|
||||
}
|
||||
|
||||
// Circumvent the password encrypted data by
|
||||
// setting the password clear. We're not storing
|
||||
// the password clear, it is just a temporary
|
||||
// object manipulation. The password will stay
|
||||
// encrypted in the database.
|
||||
if ($share->getPassword() && $share->getPassword() !== $password) {
|
||||
if (!$this->shareManager->checkPassword($share, $password)) {
|
||||
throw new OCSBadRequestException($this->l->t('Wrong password'));
|
||||
}
|
||||
$share = $share->setPassword($password);
|
||||
}
|
||||
|
||||
$provider->sendMailNotification($share);
|
||||
return new JSONResponse(['message' => 'ok']);
|
||||
} catch(OCSBadRequestException $e) {
|
||||
throw $e;
|
||||
} catch (Exception $e) {
|
||||
throw new OCSException($this->l->t('Error while sending mail notification'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,18 +101,12 @@ class ShareByMailProvider implements IShareProviderWithNotification {
|
|||
|
||||
$shareId = $this->createMailShare($share);
|
||||
|
||||
// Sends share password to receiver when it's a permanent one (otherwise she will have to request it via the showShare UI)
|
||||
// or to owner when the password shall be given during a Talk session
|
||||
if ($this->config->getSystemValue('sharing.enable_mail_link_password_expiration', false) === false || $share->getSendPasswordByTalk()) {
|
||||
$send = $this->sendPassword($share, $password);
|
||||
if ($passwordEnforced && $send === false) {
|
||||
$this->sendPasswordToOwner($share, $password);
|
||||
}
|
||||
}
|
||||
|
||||
$this->createShareActivity($share);
|
||||
$data = $this->getRawShare($shareId);
|
||||
|
||||
// Temporary set the clear password again to send it by mail
|
||||
$data['password'] = $password;
|
||||
|
||||
return $this->createShareObject($data);
|
||||
}
|
||||
|
||||
|
|
@ -260,6 +254,21 @@ class ShareByMailProvider implements IShareProviderWithNotification {
|
|||
$share->getExpirationDate(),
|
||||
$share->getNote()
|
||||
);
|
||||
|
||||
// If we have a password set, we send it to the recipient
|
||||
if ($share->getPassword()) {
|
||||
// Sends share password to receiver when it's a permanent one (otherwise she will have to request it via the showShare UI)
|
||||
// or to owner when the password shall be given during a Talk session
|
||||
$passwordExpire = $this->config->getSystemValue('sharing.enable_mail_link_password_expiration', false);
|
||||
$passwordEnforced = $this->shareManager->shareApiLinkEnforcePassword();
|
||||
if ($passwordExpire === false || $share->getSendPasswordByTalk()) {
|
||||
$send = $this->sendPassword($share, $share->getPassword());
|
||||
if ($passwordEnforced && $send === false) {
|
||||
$this->sendPasswordToOwner($share, $share->getPassword());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (HintException $hintException) {
|
||||
$this->logger->error('Failed to send share by mail.', [
|
||||
|
|
@ -289,7 +298,7 @@ class ShareByMailProvider implements IShareProviderWithNotification {
|
|||
* @param string $note note
|
||||
* @throws \Exception If mail couldn't be sent
|
||||
*/
|
||||
public function sendEmail(
|
||||
protected function sendEmail(
|
||||
string $filename,
|
||||
string $link,
|
||||
string $initiator,
|
||||
|
|
@ -318,6 +327,7 @@ class ShareByMailProvider implements IShareProviderWithNotification {
|
|||
if ($note !== '') {
|
||||
$emailTemplate->addBodyText(htmlspecialchars($note), $note);
|
||||
}
|
||||
|
||||
$emailTemplate->addBodyText(
|
||||
htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
|
||||
$text
|
||||
|
|
@ -354,13 +364,21 @@ class ShareByMailProvider implements IShareProviderWithNotification {
|
|||
}
|
||||
|
||||
$message->useTemplate($emailTemplate);
|
||||
$this->mailer->send($message);
|
||||
$failedRecipients = $this->mailer->send($message);
|
||||
if (!empty($failedRecipients)) {
|
||||
$this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* send password to recipient of a mail share
|
||||
* Send password to recipient of a mail share
|
||||
* Will return false if
|
||||
* 1. the password is empty
|
||||
* 2. the setting to send the password by mail is disabled
|
||||
* 3. the share is set to send the password by talk
|
||||
*/
|
||||
public function sendPassword(IShare $share, string $password): bool {
|
||||
protected function sendPassword(IShare $share, string $password): bool {
|
||||
$filename = $share->getNode()->getName();
|
||||
$initiator = $share->getSharedBy();
|
||||
$shareWith = $share->getSharedWith();
|
||||
|
|
@ -660,6 +678,7 @@ class ShareByMailProvider implements IShareProviderWithNotification {
|
|||
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
|
||||
->set('note', $qb->createNamedParameter($share->getNote()))
|
||||
->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
|
||||
->set('mail_send', $qb->createNamedParameter(1))
|
||||
->executeStatement();
|
||||
|
||||
if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
|
||||
|
|
|
|||
|
|
@ -1384,36 +1384,34 @@ class DefaultShareProvider implements IShareProviderWithNotification {
|
|||
|
||||
public function sendMailNotification(IShare $share): true {
|
||||
try {
|
||||
// Handle user shares
|
||||
if ($share->getShareType() === IShare::TYPE_USER) {
|
||||
$user = $this->userManager->get($share->getSharedWith());
|
||||
if ($user !== null) {
|
||||
$emailAddress = $user->getEMailAddress();
|
||||
if ($emailAddress !== null && $emailAddress !== '') {
|
||||
$userLang = $this->l10nFactory->getUserLanguage($user);
|
||||
$l = $this->l10nFactory->get('lib', $userLang);
|
||||
$this->sendUserShareMail(
|
||||
$l,
|
||||
$share->getNode()->getName(),
|
||||
$this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
|
||||
$share->getSharedBy(),
|
||||
$emailAddress,
|
||||
$share->getExpirationDate(),
|
||||
$share->getNote()
|
||||
);
|
||||
$this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId() . '.', ['app' => 'share']);
|
||||
return true;
|
||||
|
||||
}
|
||||
$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
|
||||
return false;
|
||||
}
|
||||
// Check user
|
||||
$user = $this->userManager->get($share->getSharedWith());
|
||||
if ($user === null) {
|
||||
$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle link shares
|
||||
if ($share->getShareType() === IShare::TYPE_LINK) {
|
||||
// Handle user shares
|
||||
if ($share->getShareType() === IShare::TYPE_USER) {
|
||||
// Check email address
|
||||
$emailAddress = $user->getEMailAddress();
|
||||
if ($emailAddress === null || $emailAddress === '') {
|
||||
$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
|
||||
return false;
|
||||
}
|
||||
|
||||
$userLang = $this->l10nFactory->getUserLanguage($user);
|
||||
$l = $this->l10nFactory->get('lib', $userLang);
|
||||
$this->sendUserShareMail(
|
||||
$l,
|
||||
$share->getNode()->getName(),
|
||||
$this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
|
||||
$share->getSharedBy(),
|
||||
$emailAddress,
|
||||
$share->getExpirationDate(),
|
||||
$share->getNote()
|
||||
);
|
||||
$this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId() . '.', ['app' => 'share']);
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue