diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php
index 41a5cea71..2cc2ea9ab 100644
--- a/lib/Db/CoreRequestBuilder.php
+++ b/lib/Db/CoreRequestBuilder.php
@@ -169,6 +169,7 @@ class CoreRequestBuilder {
'file_source',
'file_target',
'permissions',
+ 'attributes',
'stime',
'accepted',
'expiration',
diff --git a/lib/Db/ShareWrapperRequest.php b/lib/Db/ShareWrapperRequest.php
index ee4bcd44d..18286ad5f 100644
--- a/lib/Db/ShareWrapperRequest.php
+++ b/lib/Db/ShareWrapperRequest.php
@@ -31,16 +31,18 @@
namespace OCA\Circles\Db;
+use JsonException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\ShareWrapperNotFoundException;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Membership;
use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\ShareWrapper;
+use OCP\Files\Folder;
use OCP\Files\NotFoundException;
use OCP\Share\Exceptions\IllegalIDChangeException;
+use OCP\Share\IAttributes;
use OCP\Share\IShare;
-use OCP\Files\Folder;
/**
* Class ShareWrapperRequest
@@ -62,18 +64,18 @@ public function save(IShare $share, int $parentId = 0): int {
$qb = $this->getShareInsertSql();
$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()))
- ->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
- ->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
- ->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
- ->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
- ->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
- ->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
- ->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
- ->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
- ->setValue('password', $qb->createNamedParameter($password))
- ->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
- ->setValue('token', $qb->createNamedParameter($share->getToken()))
- ->setValue('stime', $qb->createFunction('UNIX_TIMESTAMP()'));
+ ->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
+ ->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
+ ->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
+ ->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
+ ->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
+ ->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
+ ->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
+ ->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
+ ->setValue('password', $qb->createNamedParameter($password))
+ ->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
+ ->setValue('token', $qb->createNamedParameter($share->getToken()))
+ ->setValue('stime', $qb->createFunction('UNIX_TIMESTAMP()'));
if ($parentId > 0) {
$qb->setValue('parent', $qb->createNamedParameter($parentId));
@@ -95,12 +97,15 @@ public function save(IShare $share, int $parentId = 0): int {
*/
public function update(ShareWrapper $shareWrapper): void {
$qb = $this->getShareUpdateSql();
+ $shareAttributes = $this->formatShareAttributes($shareWrapper->getAttributes());
+
$qb->set('file_target', $qb->createNamedParameter($shareWrapper->getFileTarget()))
- ->set('share_with', $qb->createNamedParameter($shareWrapper->getSharedWith()))
- ->set('uid_owner', $qb->createNamedParameter($shareWrapper->getShareOwner()))
- ->set('uid_initiator', $qb->createNamedParameter($shareWrapper->getSharedBy()))
- ->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
- ->set('permissions', $qb->createNamedParameter($shareWrapper->getPermissions()));
+ ->set('share_with', $qb->createNamedParameter($shareWrapper->getSharedWith()))
+ ->set('uid_owner', $qb->createNamedParameter($shareWrapper->getShareOwner()))
+ ->set('uid_initiator', $qb->createNamedParameter($shareWrapper->getSharedBy()))
+ ->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
+ ->set('permissions', $qb->createNamedParameter($shareWrapper->getPermissions()))
+ ->set('attributes', $qb->createNamedParameter($shareAttributes));
$qb->limitToId((int)$shareWrapper->getId());
@@ -486,4 +491,30 @@ private function deleteSharesAndChild(array $ids): void {
$qb->execute();
}
+
+
+ /**
+ * Format IAttributes to database format (JSON string)
+ * based on OC\Share20\DefaultShareProvider::formatShareAttributes();
+ */
+ private function formatShareAttributes(?IAttributes $attributes): ?string {
+ if (empty($attributes?->toArray())) {
+ return null;
+ }
+
+ $compressedAttributes = [];
+ foreach ($attributes->toArray() as $attribute) {
+ $compressedAttributes[] = [
+ $attribute['scope'],
+ $attribute['key'],
+ $attribute['enabled']
+ ];
+ }
+
+ try {
+ return json_encode($compressedAttributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
+ } catch (JsonException $e) {
+ return null;
+ }
+ }
}
diff --git a/lib/Model/ShareWrapper.php b/lib/Model/ShareWrapper.php
index 6b3a3262a..4909582bc 100644
--- a/lib/Model/ShareWrapper.php
+++ b/lib/Model/ShareWrapper.php
@@ -36,6 +36,7 @@
use OC;
use OC\Files\Cache\Cache;
use OC\Share20\Share;
+use OC\Share20\ShareAttributes;
use OCA\Circles\AppInfo\Application;
use OCA\Circles\ShareByCircleProvider;
use OCA\Circles\Tools\Db\IQueryRow;
@@ -48,6 +49,7 @@
use OCP\IUserManager;
use OCP\L10N\IFactory;
use OCP\Share\Exceptions\IllegalIDChangeException;
+use OCP\Share\IAttributes;
use OCP\Share\IShare;
/**
@@ -82,6 +84,8 @@ class ShareWrapper extends ManagedModel implements IDeserializable, IQueryRow, J
private ?Member $initiator = null;
private ?Member $owner = null;
private ?ShareToken $shareToken = null;
+ private ?IAttributes $attributes = null;
+ private bool $hideDownload = false;
public function __construct() {
$this->shareTime = new DateTime();
@@ -337,6 +341,27 @@ public function hasShareToken(): bool {
return !is_null($this->shareToken);
}
+ public function getAttributes(): ?IAttributes {
+ return $this->attributes;
+ }
+
+ public function setAttributes(?IAttributes $attributes): self {
+ $this->attributes = $attributes;
+
+ return $this;
+ }
+
+ public function getHideDownload(): bool {
+ return $this->hideDownload;
+ }
+
+ public function setHideDownload(bool $hideDownload): self {
+ $this->hideDownload = $hideDownload;
+
+ return $this;
+ }
+
+
/**
* @throws IllegalIDChangeException
*/
@@ -354,7 +379,8 @@ public function getShare(
$share->setTarget($this->getFileTarget());
$share->setProviderId($this->getProviderId());
$share->setStatus($this->getStatus());
-
+ $share->setHideDownload($this->getHideDownload());
+ $share->setAttributes($this->getAttributes());
if ($this->hasShareToken()) {
$password = $this->getShareToken()->getPassword();
if ($password !== '') {
@@ -456,6 +482,7 @@ public function import(array $data): IDeserializable {
$this->setId($this->get('id', $data))
->setShareType($this->getInt('shareType', $data))
->setPermissions($this->getInt('permissions', $data))
+ ->setHideDownload($this->getBool('hideDownload', $data))
->setItemType($this->get('itemType', $data))
->setItemSource($this->getInt('itemSource', $data))
->setItemTarget($this->get('itemTarget', $data))
@@ -524,6 +551,8 @@ public function importFromDatabase(array $data, string $prefix = ''): IQueryRow
->setToken($this->get($prefix . 'token', $data))
->setShareTime($shareTime);
+ $this->importAttributesFromDatabase($this->get('attributes', $data));
+
// if (($password = $this->get('personal_password', $data, '')) !== '') {
// $share->setPassword($this->get('personal_password', $data, ''));
// } else if (($password = $this->get('password', $data, '')) !== '') {
@@ -541,12 +570,39 @@ public function importFromDatabase(array $data, string $prefix = ''): IQueryRow
return $this;
}
+
+ /**
+ * Load from database format (JSON string) to IAttributes
+ * based on \OC\Share20\DefaultShareProvider
+ */
+ private function importAttributesFromDatabase(string $data): void {
+ if ($data === '') {
+ return;
+ }
+
+ $attributes = new ShareAttributes();
+ $compressedAttributes = json_decode($data, true);
+ if (!is_array($compressedAttributes)) {
+ return;
+ }
+
+ foreach ($compressedAttributes as $compressedAttribute) {
+ $attributes->setAttribute(...$compressedAttribute);
+ }
+
+ $this->setHideDownload(!($attributes->getAttribute('permissions', 'download') ?? true));
+ $this->setAttributes($attributes);
+ }
+
+
public function jsonSerialize(): array {
$arr = [
'id' => $this->getId(),
'shareType' => $this->getShareType(),
'providerId' => $this->getProviderId(),
'permissions' => $this->getPermissions(),
+ 'attributes' => $this->getAttributes(),
+ 'hideDownload' => $this->getHideDownload(),
'itemType' => $this->getItemType(),
'itemSource' => $this->getItemSource(),
'itemTarget' => $this->getItemTarget(),
diff --git a/lib/Service/CircleService.php b/lib/Service/CircleService.php
index b4e023e88..475ed968d 100644
--- a/lib/Service/CircleService.php
+++ b/lib/Service/CircleService.php
@@ -801,7 +801,7 @@ public function probeCircle(
* @param CircleProbe $circleProbe
* @param DataProbe|null $dataProbe
*
- * @return array
+ * @return Circle[]
* @throws InitiatorNotFoundException
* @throws RequestBuilderException
*/
diff --git a/lib/ShareByCircleProvider.php b/lib/ShareByCircleProvider.php
index 48b564233..31c379b3d 100644
--- a/lib/ShareByCircleProvider.php
+++ b/lib/ShareByCircleProvider.php
@@ -225,8 +225,9 @@ public function create(IShare $share): IShare {
public function update(IShare $share): IShare {
$wrappedShare = $this->shareWrapperService->getShareById((int)$share->getId());
$wrappedShare->setPermissions($share->getPermissions())
- ->setShareOwner($share->getShareOwner())
- ->setSharedBy($share->getSharedBy());
+ ->setShareOwner($share->getShareOwner())
+ ->setAttributes($share->getAttributes())
+ ->setSharedBy($share->getSharedBy());
$this->shareWrapperService->update($wrappedShare);
diff --git a/psalm.xml b/psalm.xml
index 81ca9131b..9ab703435 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -26,6 +26,7 @@
+
diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml
index 522091959..086779a64 100644
--- a/tests/psalm-baseline.xml
+++ b/tests/psalm-baseline.xml
@@ -430,8 +430,9 @@
-
+
Cache::cacheEntryFromData($this->getFileCache()->toCache(), OC::$server->getMimeTypeLoader())
+ $this->setAttributes($attributes)
Circle