Skip to content

Commit 39d6f8f

Browse files
committed
download permissions on share for internal/external members
Signed-off-by: Maxence Lange <[email protected]>
1 parent 56db81d commit 39d6f8f

7 files changed

+114
-23
lines changed

lib/Db/CoreRequestBuilder.php

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class CoreRequestBuilder {
169169
'file_source',
170170
'file_target',
171171
'permissions',
172+
'attributes',
172173
'stime',
173174
'accepted',
174175
'expiration',

lib/Db/ShareWrapperRequest.php

+49-18
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,18 @@
3131

3232
namespace OCA\Circles\Db;
3333

34+
use JsonException;
3435
use OCA\Circles\Exceptions\RequestBuilderException;
3536
use OCA\Circles\Exceptions\ShareWrapperNotFoundException;
3637
use OCA\Circles\Model\FederatedUser;
3738
use OCA\Circles\Model\Membership;
3839
use OCA\Circles\Model\Probes\CircleProbe;
3940
use OCA\Circles\Model\ShareWrapper;
41+
use OCP\Files\Folder;
4042
use OCP\Files\NotFoundException;
4143
use OCP\Share\Exceptions\IllegalIDChangeException;
44+
use OCP\Share\IAttributes;
4245
use OCP\Share\IShare;
43-
use OCP\Files\Folder;
4446

4547
/**
4648
* Class ShareWrapperRequest
@@ -62,18 +64,18 @@ public function save(IShare $share, int $parentId = 0): int {
6264

6365
$qb = $this->getShareInsertSql();
6466
$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()))
65-
->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
66-
->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
67-
->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
68-
->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
69-
->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
70-
->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
71-
->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
72-
->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
73-
->setValue('password', $qb->createNamedParameter($password))
74-
->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
75-
->setValue('token', $qb->createNamedParameter($share->getToken()))
76-
->setValue('stime', $qb->createFunction('UNIX_TIMESTAMP()'));
67+
->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
68+
->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
69+
->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
70+
->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
71+
->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
72+
->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
73+
->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
74+
->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
75+
->setValue('password', $qb->createNamedParameter($password))
76+
->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
77+
->setValue('token', $qb->createNamedParameter($share->getToken()))
78+
->setValue('stime', $qb->createFunction('UNIX_TIMESTAMP()'));
7779

7880
if ($parentId > 0) {
7981
$qb->setValue('parent', $qb->createNamedParameter($parentId));
@@ -95,12 +97,15 @@ public function save(IShare $share, int $parentId = 0): int {
9597
*/
9698
public function update(ShareWrapper $shareWrapper): void {
9799
$qb = $this->getShareUpdateSql();
100+
$shareAttributes = $this->formatShareAttributes($shareWrapper->getAttributes());
101+
98102
$qb->set('file_target', $qb->createNamedParameter($shareWrapper->getFileTarget()))
99-
->set('share_with', $qb->createNamedParameter($shareWrapper->getSharedWith()))
100-
->set('uid_owner', $qb->createNamedParameter($shareWrapper->getShareOwner()))
101-
->set('uid_initiator', $qb->createNamedParameter($shareWrapper->getSharedBy()))
102-
->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
103-
->set('permissions', $qb->createNamedParameter($shareWrapper->getPermissions()));
103+
->set('share_with', $qb->createNamedParameter($shareWrapper->getSharedWith()))
104+
->set('uid_owner', $qb->createNamedParameter($shareWrapper->getShareOwner()))
105+
->set('uid_initiator', $qb->createNamedParameter($shareWrapper->getSharedBy()))
106+
->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
107+
->set('permissions', $qb->createNamedParameter($shareWrapper->getPermissions()))
108+
->set('attributes', $qb->createNamedParameter($shareAttributes));
104109

105110
$qb->limitToId((int)$shareWrapper->getId());
106111

@@ -486,4 +491,30 @@ private function deleteSharesAndChild(array $ids): void {
486491

487492
$qb->execute();
488493
}
494+
495+
496+
/**
497+
* Format IAttributes to database format (JSON string)
498+
* based on OC\Share20\DefaultShareProvider::formatShareAttributes();
499+
*/
500+
private function formatShareAttributes(?IAttributes $attributes): ?string {
501+
if (empty($attributes?->toArray())) {
502+
return null;
503+
}
504+
505+
$compressedAttributes = [];
506+
foreach ($attributes->toArray() as $attribute) {
507+
$compressedAttributes[] = [
508+
$attribute['scope'],
509+
$attribute['key'],
510+
$attribute['enabled']
511+
];
512+
}
513+
514+
try {
515+
return json_encode($compressedAttributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
516+
} catch (JsonException $e) {
517+
return null;
518+
}
519+
}
489520
}

lib/Model/ShareWrapper.php

+57-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
use OC;
3737
use OC\Files\Cache\Cache;
3838
use OC\Share20\Share;
39+
use OC\Share20\ShareAttributes;
3940
use OCA\Circles\AppInfo\Application;
4041
use OCA\Circles\ShareByCircleProvider;
4142
use OCA\Circles\Tools\Db\IQueryRow;
@@ -48,6 +49,7 @@
4849
use OCP\IUserManager;
4950
use OCP\L10N\IFactory;
5051
use OCP\Share\Exceptions\IllegalIDChangeException;
52+
use OCP\Share\IAttributes;
5153
use OCP\Share\IShare;
5254

5355
/**
@@ -82,6 +84,8 @@ class ShareWrapper extends ManagedModel implements IDeserializable, IQueryRow, J
8284
private ?Member $initiator = null;
8385
private ?Member $owner = null;
8486
private ?ShareToken $shareToken = null;
87+
private ?IAttributes $attributes = null;
88+
private bool $hideDownload = false;
8589

8690
public function __construct() {
8791
$this->shareTime = new DateTime();
@@ -337,6 +341,27 @@ public function hasShareToken(): bool {
337341
return !is_null($this->shareToken);
338342
}
339343

344+
public function getAttributes(): ?IAttributes {
345+
return $this->attributes;
346+
}
347+
348+
public function setAttributes(?IAttributes $attributes): self {
349+
$this->attributes = $attributes;
350+
351+
return $this;
352+
}
353+
354+
public function getHideDownload(): bool {
355+
return $this->hideDownload;
356+
}
357+
358+
public function setHideDownload(bool $hideDownload): self {
359+
$this->hideDownload = $hideDownload;
360+
361+
return $this;
362+
}
363+
364+
340365
/**
341366
* @throws IllegalIDChangeException
342367
*/
@@ -354,7 +379,8 @@ public function getShare(
354379
$share->setTarget($this->getFileTarget());
355380
$share->setProviderId($this->getProviderId());
356381
$share->setStatus($this->getStatus());
357-
382+
$share->setHideDownload($this->getHideDownload());
383+
$share->setAttributes($this->getAttributes());
358384
if ($this->hasShareToken()) {
359385
$password = $this->getShareToken()->getPassword();
360386
if ($password !== '') {
@@ -456,6 +482,7 @@ public function import(array $data): IDeserializable {
456482
$this->setId($this->get('id', $data))
457483
->setShareType($this->getInt('shareType', $data))
458484
->setPermissions($this->getInt('permissions', $data))
485+
->setHideDownload($this->getBool('hideDownload', $data))
459486
->setItemType($this->get('itemType', $data))
460487
->setItemSource($this->getInt('itemSource', $data))
461488
->setItemTarget($this->get('itemTarget', $data))
@@ -524,6 +551,8 @@ public function importFromDatabase(array $data, string $prefix = ''): IQueryRow
524551
->setToken($this->get($prefix . 'token', $data))
525552
->setShareTime($shareTime);
526553

554+
$this->importAttributesFromDatabase($this->get('attributes', $data));
555+
527556
// if (($password = $this->get('personal_password', $data, '')) !== '') {
528557
// $share->setPassword($this->get('personal_password', $data, ''));
529558
// } else if (($password = $this->get('password', $data, '')) !== '') {
@@ -541,12 +570,39 @@ public function importFromDatabase(array $data, string $prefix = ''): IQueryRow
541570
return $this;
542571
}
543572

573+
574+
/**
575+
* Load from database format (JSON string) to IAttributes
576+
* based on \OC\Share20\DefaultShareProvider
577+
*/
578+
private function importAttributesFromDatabase(string $data): void {
579+
if ($data === '') {
580+
return;
581+
}
582+
583+
$attributes = new ShareAttributes();
584+
$compressedAttributes = json_decode($data, true);
585+
if (!is_array($compressedAttributes)) {
586+
return;
587+
}
588+
589+
foreach ($compressedAttributes as $compressedAttribute) {
590+
$attributes->setAttribute(...$compressedAttribute);
591+
}
592+
593+
$this->setHideDownload(!($attributes->getAttribute('permissions', 'download') ?? true));
594+
$this->setAttributes($attributes);
595+
}
596+
597+
544598
public function jsonSerialize(): array {
545599
$arr = [
546600
'id' => $this->getId(),
547601
'shareType' => $this->getShareType(),
548602
'providerId' => $this->getProviderId(),
549603
'permissions' => $this->getPermissions(),
604+
'attributes' => $this->getAttributes(),
605+
'hideDownload' => $this->getHideDownload(),
550606
'itemType' => $this->getItemType(),
551607
'itemSource' => $this->getItemSource(),
552608
'itemTarget' => $this->getItemTarget(),

lib/Service/CircleService.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ public function probeCircle(
801801
* @param CircleProbe $circleProbe
802802
* @param DataProbe|null $dataProbe
803803
*
804-
* @return array
804+
* @return Circle[]
805805
* @throws InitiatorNotFoundException
806806
* @throws RequestBuilderException
807807
*/

lib/ShareByCircleProvider.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,9 @@ public function create(IShare $share): IShare {
225225
public function update(IShare $share): IShare {
226226
$wrappedShare = $this->shareWrapperService->getShareById((int)$share->getId());
227227
$wrappedShare->setPermissions($share->getPermissions())
228-
->setShareOwner($share->getShareOwner())
229-
->setSharedBy($share->getSharedBy());
228+
->setShareOwner($share->getShareOwner())
229+
->setAttributes($share->getAttributes())
230+
->setSharedBy($share->getSharedBy());
230231

231232
$this->shareWrapperService->update($wrappedShare);
232233

psalm.xml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<errorLevel type="suppress">
2727
<referencedClass name="OC" />
2828
<referencedClass name="Doctrine\DBAL\Schema\SchemaException" />
29+
<referencedClass name="OC\Share20\ShareAttributes" />
2930
</errorLevel>
3031
</UndefinedClass>
3132
<UndefinedDocblockClass>

tests/psalm-baseline.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,9 @@
430430
</InvalidReturnType>
431431
</file>
432432
<file src="lib/Model/ShareWrapper.php">
433-
<InvalidArgument occurrences="1">
433+
<InvalidArgument occurrences="2">
434434
<code>Cache::cacheEntryFromData($this-&gt;getFileCache()-&gt;toCache(), OC::$server-&gt;getMimeTypeLoader())</code>
435+
<code>$this-&gt;setAttributes($attributes)</code>
435436
</InvalidArgument>
436437
<InvalidNullableReturnType occurrences="5">
437438
<code>Circle</code>

0 commit comments

Comments
 (0)