Skip to content

Commit 75ca494

Browse files
committed
feat(files_sharing): allow mixed values in share attributes and allow storing email arrays
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
1 parent c253112 commit 75ca494

File tree

11 files changed

+76
-35
lines changed

11 files changed

+76
-35
lines changed

apps/files_sharing/lib/Controller/ShareAPIController.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1986,10 +1986,17 @@ private function setShareAttributes(IShare $share, ?string $attributesString) {
19861986
$formattedShareAttributes = \json_decode($attributesString, true);
19871987
if (is_array($formattedShareAttributes)) {
19881988
foreach ($formattedShareAttributes as $formattedAttr) {
1989+
// Legacy handling of the 'enabled' attribute
1990+
if ($formattedAttr['enabled']) {
1991+
$formattedAttr['value'] = is_string($formattedAttr['enabled'])
1992+
? (bool) \json_decode($formattedAttr['enabled'])
1993+
: $formattedAttr['enabled'];
1994+
}
1995+
19891996
$newShareAttributes->setAttribute(
19901997
$formattedAttr['scope'],
19911998
$formattedAttr['key'],
1992-
is_string($formattedAttr['enabled']) ? (bool) \json_decode($formattedAttr['enabled']) : $formattedAttr['enabled']
1999+
$formattedAttr['value'],
19932000
);
19942001
}
19952002
} else {

apps/files_sharing/lib/MountProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ private function buildSuperShares(array $allShares, \OCP\IUser $user) {
215215
continue;
216216
}
217217
// update supershare attributes with subshare attribute
218-
$superAttributes->setAttribute($attribute['scope'], $attribute['key'], $attribute['enabled']);
218+
$superAttributes->setAttribute($attribute['scope'], $attribute['key'], $attribute['value']);
219219
}
220220
}
221221

apps/files_sharing/src/components/NewFileRequestDialog.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ export default defineComponent({
244244
try {
245245
const request = await axios.post(shareUrl, {
246246
path: this.destination,
247-
shareType: Type.SHARE_TYPE_LINK,
247+
shareType: Type.SHARE_TYPE_EMAIL,
248248
publicUpload: 'true',
249249
password: this.password || undefined,
250250
expireDate,

apps/files_sharing/src/components/SharingEntryLink.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ export default {
554554
},
555555
556556
canChangeHideDownload() {
557-
const hasDisabledDownload = (shareAttribute) => shareAttribute.key === 'download' && shareAttribute.scope === 'permissions' && shareAttribute.enabled === false
557+
const hasDisabledDownload = (shareAttribute) => shareAttribute.key === 'download' && shareAttribute.scope === 'permissions' && shareAttribute.value === false
558558
return this.fileInfo.shareAttributes.some(hasDisabledDownload)
559559
},
560560
},

apps/files_sharing/src/mixins/ShareDetails.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default {
4646
const share = {
4747
attributes: [
4848
{
49-
enabled: true,
49+
value: true,
5050
key: 'download',
5151
scope: 'permissions',
5252
},

apps/files_sharing/src/models/Share.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ export default class Share {
535535
for (const i in this._share.attributes) {
536536
const attr = this._share.attributes[i]
537537
if (attr.scope === 'permissions' && attr.key === 'download') {
538-
return attr.enabled
538+
return attr.value
539539
}
540540
}
541541

@@ -546,11 +546,11 @@ export default class Share {
546546
this.setAttribute('permissions', 'download', !!enabled)
547547
}
548548

549-
setAttribute(scope, key, enabled) {
549+
setAttribute(scope, key, value) {
550550
const attrUpdate = {
551551
scope,
552552
key,
553-
enabled,
553+
value,
554554
}
555555

556556
// try and replace existing

apps/files_sharing/src/views/SharingDetailsTab.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,13 @@ export default {
421421
*/
422422
canDownload: {
423423
get() {
424-
return this.share.attributes.find(attr => attr.key === 'download')?.enabled || false
424+
return this.share.attributes.find(attr => attr.key === 'download')?.value || false
425425
},
426426
set(checked) {
427427
// Find the 'download' attribute and update its value
428428
const downloadAttr = this.share.attributes.find(attr => attr.key === 'download')
429429
if (downloadAttr) {
430-
downloadAttr.enabled = checked
430+
downloadAttr.value = checked
431431
}
432432
},
433433
},
@@ -678,7 +678,7 @@ export default {
678678
return OC.appswebroots.spreed !== undefined
679679
},
680680
canChangeHideDownload() {
681-
const hasDisabledDownload = (shareAttribute) => shareAttribute.key === 'download' && shareAttribute.scope === 'permissions' && shareAttribute.enabled === false
681+
const hasDisabledDownload = (shareAttribute) => shareAttribute.key === 'download' && shareAttribute.scope === 'permissions' && shareAttribute.value === false
682682
return this.fileInfo.shareAttributes.some(hasDisabledDownload)
683683
},
684684
customPermissionsList() {

apps/sharebymail/lib/ShareByMailProvider.php

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace OCA\ShareByMail;
77

8+
use OC\Share20\DefaultShareProvider;
89
use OC\Share20\Exception\InvalidShare;
910
use OC\Share20\Share;
1011
use OC\User\NoUserException;
@@ -29,6 +30,7 @@
2930
use OCP\Security\ISecureRandom;
3031
use OCP\Share\Exceptions\GenericShareException;
3132
use OCP\Share\Exceptions\ShareNotFound;
33+
use OCP\Share\IAttributes;
3234
use OCP\Share\IManager as IShareManager;
3335
use OCP\Share\IShare;
3436
use OCP\Share\IShareProviderWithNotification;
@@ -39,7 +41,7 @@
3941
*
4042
* @package OCA\ShareByMail
4143
*/
42-
class ShareByMailProvider implements IShareProviderWithNotification {
44+
class ShareByMailProvider extends DefaultShareProvider implements IShareProviderWithNotification {
4345
/**
4446
* Return the identifier of this provider.
4547
*
@@ -76,11 +78,10 @@ public function __construct(
7678
*/
7779
public function create(IShare $share): IShare {
7880
$shareWith = $share->getSharedWith();
79-
/*
80-
* Check if file is not already shared with the remote user
81-
*/
81+
// Check if file is not already shared with the given email,
82+
// if we have an email at all.
8283
$alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_EMAIL, $share->getNode(), 1, 0);
83-
if (!empty($alreadyShared)) {
84+
if ($shareWith !== '' && !empty($alreadyShared)){
8485
$message = 'Sharing %1$s failed, because this item is already shared with the account %2$s';
8586
$message_t = $this->l->t('Sharing %1$s failed, because this item is already shared with the account %2$s', [$share->getNode()->getName(), $shareWith]);
8687
$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
@@ -224,7 +225,8 @@ protected function createMailShare(IShare $share): int {
224225
$share->getHideDownload(),
225226
$share->getLabel(),
226227
$share->getExpirationDate(),
227-
$share->getNote()
228+
$share->getNote(),
229+
$share->getAttributes(),
228230
);
229231
}
230232

@@ -233,11 +235,17 @@ protected function createMailShare(IShare $share): int {
233235
*/
234236
public function sendMailNotification(IShare $share): bool {
235237
$shareId = $share->getId();
236-
if (!$this->mailer->validateMailAddress($share->getSharedWith())) {
238+
239+
$emails = $this->getSharedWithEmails($share);
240+
$validEmails = array_filter($emails, function ($email) {
241+
return $this->mailer->validateMailAddress($email);
242+
});
243+
244+
if (count($validEmails) === 0) {
237245
$this->removeShareFromTable($shareId);
238-
$e = new HintException('Failed to send share by mail. Got an invalid email address: ' . $share->getSharedWith(),
246+
$e = new HintException('Failed to send share by mail. Could not find a valid email address: ' . join(', ', $emails),
239247
$this->l->t('Failed to send share by email. Got an invalid email address'));
240-
$this->logger->error('Failed to send share by mail. Got an invalid email address ' . $share->getSharedWith(), [
248+
$this->logger->error('Failed to send share by mail. Could not find a valid email address ' . join(', ', $emails), [
241249
'app' => 'sharebymail',
242250
'exception' => $e,
243251
]);
@@ -250,7 +258,7 @@ public function sendMailNotification(IShare $share): bool {
250258
$share->getNode()->getName(),
251259
$link,
252260
$share->getSharedBy(),
253-
$share->getSharedWith(),
261+
$emails,
254262
$share->getExpirationDate(),
255263
$share->getNote()
256264
);
@@ -293,7 +301,7 @@ public function sendMailNotification(IShare $share): bool {
293301
* @param string $filename file/folder name
294302
* @param string $link link to the file/folder
295303
* @param string $initiator user ID of share sender
296-
* @param string $shareWith email addresses
304+
* @param string[] $shareWith email addresses
297305
* @param \DateTime|null $expiration expiration date
298306
* @param string $note note
299307
* @throws \Exception If mail couldn't be sent
@@ -302,7 +310,7 @@ protected function sendEmail(
302310
string $filename,
303311
string $link,
304312
string $initiator,
305-
string $shareWith,
313+
array $shareWith,
306314
?\DateTime $expiration = null,
307315
string $note = '',
308316
): void {
@@ -337,7 +345,13 @@ protected function sendEmail(
337345
$link
338346
);
339347

340-
$message->setTo([$shareWith]);
348+
// If multiple recipients are given, we send the mail to all of them
349+
if (count($shareWith) > 1) {
350+
// We do not want to expose the email addresses of the other recipients
351+
$message->setBcc($shareWith);
352+
} else {
353+
$message->setTo($shareWith);
354+
}
341355

342356
// The "From" contains the sharers name
343357
$instanceName = $this->defaults->getName();
@@ -618,7 +632,8 @@ protected function addShareToDB(
618632
?bool $hideDownload,
619633
?string $label,
620634
?\DateTimeInterface $expirationTime,
621-
?string $note = ''
635+
?string $note = '',
636+
?IAttributes $attributes = null,
622637
): int {
623638
$qb = $this->dbConnection->getQueryBuilder();
624639
$qb->insert('share')
@@ -640,6 +655,10 @@ protected function addShareToDB(
640655
->setValue('note', $qb->createNamedParameter($note))
641656
->setValue('mail_send', $qb->createNamedParameter(1));
642657

658+
// set share attributes
659+
$shareAttributes = $this->formatShareAttributes($attributes);
660+
661+
$qb->setValue('attributes', $qb->createNamedParameter($shareAttributes));
643662
if ($expirationTime !== null) {
644663
$qb->setValue('expiration', $qb->createNamedParameter($expirationTime, IQueryBuilder::PARAM_DATE));
645664
}
@@ -955,6 +974,8 @@ protected function createShareObject(array $data): IShare {
955974
}
956975
}
957976

977+
$share = $this->updateShareAttributes($share, $data['attributes']);
978+
958979
$share->setNodeId((int)$data['file_source']);
959980
$share->setNodeType($data['item_type']);
960981

@@ -1137,4 +1158,17 @@ public function getAllShares(): iterable {
11371158
}
11381159
$cursor->closeCursor();
11391160
}
1161+
1162+
/**
1163+
* Extract the emails from the share
1164+
* It can be a single email, from the share_with field
1165+
* or a list of emails from the emails attributes field.
1166+
*/
1167+
protected function getSharedWithEmails(IShare $share) {
1168+
$attributes = $share->getAttributes()->getAttribute('sharedWith', 'emails');
1169+
if (isset($attributes) && is_array($attributes) && !empty($attributes)) {
1170+
return $attributes;
1171+
}
1172+
return [$share->getSharedWith()];
1173+
}
11401174
}

lib/private/Share20/DefaultShareProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,7 @@ private function propagateNote(IShare $share) {
13821382
}
13831383
}
13841384

1385-
public function sendMailNotification(IShare $share): true {
1385+
public function sendMailNotification(IShare $share): bool {
13861386
try {
13871387
// Check user
13881388
$user = $this->userManager->get($share->getSharedWith());
@@ -1616,7 +1616,7 @@ public function getAllShares(): iterable {
16161616
*
16171617
* @return IShare the modified share
16181618
*/
1619-
private function updateShareAttributes(IShare $share, ?string $data): IShare {
1619+
protected function updateShareAttributes(IShare $share, ?string $data): IShare {
16201620
if ($data !== null && $data !== '') {
16211621
$attributes = new ShareAttributes();
16221622
$compressedAttributes = \json_decode($data, true);
@@ -1639,7 +1639,7 @@ private function updateShareAttributes(IShare $share, ?string $data): IShare {
16391639
/**
16401640
* Format IAttributes to database format (JSON string)
16411641
*/
1642-
private function formatShareAttributes(?IAttributes $attributes): ?string {
1642+
protected function formatShareAttributes(?IAttributes $attributes): ?string {
16431643
if ($attributes === null || empty($attributes->toArray())) {
16441644
return null;
16451645
}
@@ -1649,7 +1649,7 @@ private function formatShareAttributes(?IAttributes $attributes): ?string {
16491649
$compressedAttributes[] = [
16501650
0 => $attribute['scope'],
16511651
1 => $attribute['key'],
1652-
2 => $attribute['enabled']
1652+
2 => $attribute['value']
16531653
];
16541654
}
16551655
return \json_encode($compressedAttributes);

lib/private/Share20/ShareAttributes.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ public function __construct() {
2020
/**
2121
* @inheritdoc
2222
*/
23-
public function setAttribute($scope, $key, $enabled) {
23+
public function setAttribute($scope, $key, $value) {
2424
if (!\array_key_exists($scope, $this->attributes)) {
2525
$this->attributes[$scope] = [];
2626
}
27-
$this->attributes[$scope][$key] = $enabled;
27+
$this->attributes[$scope][$key] = $value;
2828
return $this;
2929
}
3030

@@ -45,11 +45,11 @@ public function getAttribute($scope, $key) {
4545
public function toArray() {
4646
$result = [];
4747
foreach ($this->attributes as $scope => $keys) {
48-
foreach ($keys as $key => $enabled) {
48+
foreach ($keys as $key => $value) {
4949
$result[] = [
5050
"scope" => $scope,
5151
"key" => $key,
52-
"enabled" => $enabled
52+
"value" => $value
5353
];
5454
}
5555
}

0 commit comments

Comments
 (0)